Linux进程与线程之四

2024-05-19 10:18
文章标签 linux 线程 进程 之四

本文主要是介绍Linux进程与线程之四,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


                     每日一结

一 传统的进程间通信 

1.信号 : 异步进程间通信方式 

 

信号是对中断机制的一种模拟 

进程对信号处理方式:

(1)忽略信号 

SIGKILL ,SIGSTOP 不能忽略 

(2)捕捉 : 信号到达的时候,执行信号处理函数 

(3)缺省操作 : 系统默认的操作 

大部分信号默认的操作都是杀死进程,SIGCHLD 进程默认忽略。

SIGCHLD在子进程状态发生改变的时候,发送父进程 。

 

2.设置进程对信号的处理方式 

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

参数:

@signum    信号序号 

@handler   SIG_IGN:忽略  SIG_DFL:默认的处理方式   函数名:捕捉 

返回值:

成功返回处理函数的入口地址,失败返回SIG_ERR 

注:查看一下man page,解释一下其中的参数,以及总结一下,对于这类参数,该怎么去看。

 

练习:

回收僵尸态子进程,父进程不能轮询,不能阻塞 ?

(1).创建一个子进程,睡眠3s后退出 

(2).父进程每隔1s输出一个字符串 

wait / waitpid

 

3.设置闹钟 

unsigned int alarm(unsigned int seconds);

功能:给进程启动一个定时器,定时器时间达到,内核会向进程发送SIGALRM 

参数:

@seconds  秒 

返回值:

成功返回0,失败返回 -1 

练习:

探测用户有没有输入,如果3s内用户没有输入,则超时一次 ,如果超时三次进程自动结束 

代码示例如下:



 

代码分析如下:

思考一下,其整个进程运行的流程

 

4.挂起进程 

int  pause(void);

特点:挂起一个进程,直到进程收到一个信号,进程会继续执行 


代码示例如下:


分析其原因:

 

 

注意:对于这个程序的运行结果,自己好好思考一下

 

注意:大部分信号对进程的默认操作都是杀死进程,此时必须设置进程对信号处理方式为捕捉 

 

信号是个什么东西?信号是怎么进行进程间通信的?

信号是在软件层次上对中断机制的一种模拟。在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的。信号是异步的:一个进程不必通过任何操作来等待信号的到达。事实上,进程也不知道信号到底什么时候到达。信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了那些系统事件。他可以在任何时候发给某一进程,而无需知道该进程的状态。如果该进程当前并未处于执行态,则该信号就有内核保存起来,知道该进程恢复执行再传递给它为止;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,知道其阻塞被取消时才被传递给进程。信号是进程间通信机制中唯一的异步通信机制。

 

怎么区分同步通知和异步通知?

信号可以直接进行用户空间进程和内核进程之间的交互

 

同步和异步的区别:
1、同步就是说多个任务之间是有先后关系的,一个任务需要等待另一个任务执行完毕才能继续执行。
2、异步就是说多个任务之间没有先后关系,不需要相互等待各做各的事。

同步编程方法:
1、信号量
2、互斥量

异步无需考虑资源冲突,不需特别处理。


关于Linux环境进程间通信的参考资料(二): 信号
上:http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html
下:http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index2.html


二 IPC对象 

1.消息队列 

(1)创建消息队列 

int msgget(key_t key, int msgflg);

功能:获取指定的key值的消息队列ID

参数:

@key  

<1>IPC_PRIVATE:每次都会创建一个新的消息队列 [用在亲缘关系的进程间通信]

<2>ftok函数获的key [用在非亲缘关系进程间通信]

key_t ftok(const char *pathname, int proj_id);

功能:根据文件的ID 和 proj_id的低8bit产生一个key值 

参数:

@pathname  一个文件名 

@proj_id   一个字符

返回值:

成功返回key,失败返回-1 

 

@msgflg :IPC_CREAT , IPC_EXCL

IPC_CREAT | 0666  -> 如果执行的key的消息队列不存在,则创建新的消息队列 

IPC_CREAT | IPC_EXCL -> 判别指定key的消息队列是否存在,如果存在则报错 

返回值:

成功返回消息队列ID,失败返回-1

--------------------------------------------------

通过命令查看IPC对象:

ipcs  -m/-s/-q

m:共享内存对象

s:信号灯集对象 

q:消息队列对象 

ipcrm -m/-s/-q  ID 

删除IPC对象 

--------------------------------------------------

(2)添加消息 

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

参数:

@msqid  消息队列的ID 

@msgp   消息存放的地址 

@msgsz  消息正文的大小 

@msgflg 0:阻塞的方式调用   IPC_NOWAIT:非阻塞的方式调用 

 

返回值:成功返回0,失败返回-1 

-----------------------------------------------------------

消息结构体:

typedef struct 

{

//第一个字段必须是消息类型

long type;

//消息正文部分 

char buf[1024];

int pid;

..

}MSG;

 

//计算消息正文的大小 

#define MTXT_SIZE  (sizeof(MSG) - sizeof(long))

-----------------------------------------------------------

MSG msg;

 

msg.type = 100;

fgets(msg.buf,sizeof(msg.buf),stdin);

msg.pid = getpid();

 

msgsnd(msgid,&msg,MTXT_SIZE,0);

 

(3)接受消息

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

参数:

@msqid  消息队列的ID 

@msgp   消息存放的地址 

@msgsz  消息正文的大小 

@msgtyp 消息的类型

@msgflg 0:阻塞的方式调用   IPC_NOWAIT:非阻塞的方式调用 

返回值:成功返回接受的消息正文大小,失败返回-1 

 

练习:

A,B进程通过消息队列通信[A,B进程没有亲缘关系]

示例如下:

 

进程A:




 

 

 

进程B:




 

代码分析如下:

 

关于Linux环境进程间通信的参考资料:

消息队列
http://www.ibm.com/developerworks/cn/linux/l-ipc/part3/

 

Linux下进程间通信方式的概述:

I.传统的进程间通信方式

有名管道(pipe),有名管道(fifo)和信号(signal)

II.system V IPC对象

共享内存(share memory),消息队列(message queue)和信号灯(semaphore)

III.BSD

套接字(socket)




关注微信公众号获取更多资讯


这篇关于Linux进程与线程之四的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/995815

相关文章

linux生产者,消费者问题

pthread_cond_wait() :用于阻塞当前线程,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast来唤醒它。 pthread_cond_wait() 必须与pthread_mutex 配套使用。pthread_cond_wait()函数一进入wait状态就会自动release mutex。当其他线程通过pthread

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人习惯的路径 /opt/tomcat-10

RedHat运维-Linux文本操作基础-AWK进阶

你不用整理,跟着敲一遍,有个印象,然后把它保存到本地,以后要用再去看,如果有了新东西,你自个再添加。这是我参考牛客上的shell编程专项题,只不过换成了问答的方式而已。不用背,就算是我自己亲自敲,我现在好多也记不住。 1. 输出nowcoder.txt文件第5行的内容 2. 输出nowcoder.txt文件第6行的内容 3. 输出nowcoder.txt文件第7行的内容 4. 输出nowcode

【Linux进阶】UNIX体系结构分解——操作系统,内核,shell

1.什么是操作系统? 从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境。我们通常将这种软件称为内核(kerel),因为它相对较小,而且位于环境的核心。  从广义上说,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,并使计算机具有自己的特生。这里所说的其他软件包括系统实用程序(system utility)、应用程序、shell以及公用函数库等

Windows/macOS/Linux 安装 Redis 和 Redis Desktop Manager 可视化工具

本文所有安装都在macOS High Sierra 10.13.4进行,Windows安装相对容易些,Linux安装与macOS类似,文中会做区分讲解 1. Redis安装 1.下载Redis https://redis.io/download 把下载的源码更名为redis-4.0.9-source,我喜欢跟maven、Tomcat放在一起,就放到/Users/zhan/Documents

Linux系统稳定性的奥秘:探究其背后的机制与哲学

在计算机操作系统的世界里,Linux以其卓越的稳定性和可靠性著称,成为服务器、嵌入式系统乃至个人电脑用户的首选。那么,是什么造就了Linux如此之高的稳定性呢?本文将深入解析Linux系统稳定性的几个关键因素,揭示其背后的技术哲学与实践。 1. 开源协作的力量Linux是一个开源项目,意味着任何人都可以查看、修改和贡献其源代码。这种开放性吸引了全球成千上万的开发者参与到内核的维护与优化中,形成了

Linux 下的Vim命令宝贝

vim 命令详解(转自:https://www.cnblogs.com/usergaojie/p/4583796.html) vi: Visual Interface 可视化接口 vim: VI iMproved VI增强版 全屏编辑器,模式化编辑器 vim模式: 编辑模式(命令模式)输入模式末行模式 模式转换: 编辑-->输入: i: 在当前光标所在字符的前面,转为输入模式

Linux和Mac分卷压缩

使用 zip 命令压缩文件 使用 zip 命令压缩文件,并结合 split 命令来分卷: zip - largefile | split -b 500k 举例: zip - ./tomcat.dmg |split -b 500k 上述命令将文件 largefile 压缩成 zip 包并分卷成不超过 500k 的文件,分解后文件名默认是 x* ,后缀为 2 位a-z 字母,如 aa、ab。

Linux文本三剑客sed

sed和awk grep就是查找文本当中的内容,最强大的功能就是使用扩展正则表达式 sed sed是一种流编辑器,一次处理一行内容。 如果只是展示,会放在缓冲区(模式空间),展示结束后,会从模式空间把结果删除 一行行处理,处理完当前行,才会处理下一行。直到文件的末尾。 sed的命令格式和操作选项: sed -e '操作符 ' -e '操作符' 文件1 文件2 -e表示可以跟多个操作

Linux中拷贝 cp命令中拷贝所有的写法详解

This text from: http://www.jb51.net/article/101641.htm 一、预备  cp就是拷贝,最简单的使用方式就是: cp oldfile newfile 但这样只能拷贝文件,不能拷贝目录,所以通常用: cp -r old/ new/ 那就会把old目录整个拷贝到new目录下。注意,不是把old目录里面的文件拷贝到new目录,