Linux popen相关信号

SIGCHLD信号用于通知父进程子进程已结束,避免僵尸进程。popen不屏蔽SIGCHLD以允许并行执行。信号处理包括阻塞、非阻塞和屏蔽,处理不当可能导致并发问题。在编写信号处理器时需考虑安全,尤其是在共享全局变量时。
摘要由CSDN通过智能技术生成

由于popen是靠fork子进程来完成和shell命令的通信的,和子进程相关的几个信号:SIGCHLD SIGINT SIGQUIT

SIGCHLD 

为了避免出现僵尸进程,父进程需要使用wait或waitpid函数等待子进程结束,父进程可以阻塞等待子进程结束,也可以非阻塞地查询的是否有子进程结束等待清理,即轮询的方式。

  • 如果采用阻塞等待:父进程阻塞就不能处理自己的工作了
  • 如果采用非阻塞等待:父进程在处理自己的工作的同时还要记得时不时地轮询一下,程序实现复杂

子进程在终止时会给父进程发生SIGCHLD信号,该信号的默认处理动作是忽略,父进程可以自定义SIGCHLD信号的处理动作,这样父进程就只需专心处理自己的工作,不必关心子进程了,子进程终止时会通知父进程,父进程在信号处理函数中调用wait或waitpid函数清理子进程即可。

SIGCHLD是子进程退出的时候发给父进程的一个信号,system()中为什么要屏蔽SIGCHLD信号可以参考:system函数的总结、waitpid(or wait)和SIGCHILD的关系,总结一句就是为了system()调用能够及时的退出并且能够正确的获取子进程的退出状态(成功回收子进程)。

popen没有屏蔽SIGCHLD,主要的原因就是popen是”并行”的。如果我们在调用popen的时候屏蔽了SIGCHLD,那么如果在调用popen和pclose之间调用进程又创建了其它的子进程并且调用进程注册了SIGCHLD信号处理句柄来处理子进程的回收工作(waitpid)那么这个回收工作会一直阻塞到pclose调用。

Linux信号处理

Linux信号处理的三种方式,Linux安全的信号处理方式 - 百度文库

Linux中的信号屏蔽

在linux的进程中可以接收到各种的信号,并且如果你不对信号进行处理,linux中的进程就会采用默认的处理方式处理,比如ctrl+c的信号,进程对它的处理就是终止进程的执行。我们可以在进程中屏蔽掉某些信号,使进程不去处理这些信号。

在linux中,每个进程都拥有两个位向量,这两个位向量共同决定了进程将如何处理信号;

一个是pending位向量,它包含了那些内核发送给进程,但是还没被进程处理掉的信号;

另一个是blocked位向量,它包含了那些被进程屏蔽掉的信号。

当内核发送一个信号给进程时,它将会修改进程的pending位向量,譬如说,当内核发送一个SIGINT信号给进程,那么它会将进程的pending【SIGINT】的值设置成1;

同样地,当进程屏蔽掉一个信号时,它会修改blocked位向量。那么信号屏蔽是什么意思呢?当进程屏蔽掉一个信号之后,内核仍然可以发送这个信号给进程(保存在进程的pending位向量中),但进程不会接收并处理这个信号。只有当进程解除了对这个信号的屏蔽之后,进程才会接收并处理这个信号。

从内核的角度看,大概是这样的:当内核执行context switch切换到某个进程的时候,它会检查进程的pending和blocking位向量。如果发现进程还有信号未处理,同时这个信号没有被进程屏蔽,那么内核就会让进程接收并处理这个信号。

安全地处理信号

通常来说,信号中断有两种情况:

当进程接收到某个信号时,会调用这个信号的handler,这会中断主程序的执行;

当进程执行某个信号的handler的过程中个,可能会被另一个信号handler中断;

上面这两种情况都会带来并发安全的问题,因此在编写信号handler时,需要考虑到并发安全的问题。譬如说,由于信号handler会中断主程序的执行,如果信号handler与主程序共享全局变量,就可能带来并发安全的问题。

信号handler与主程序共享全局变量是很常见的。譬如说,当进程在接收到SIGINT时,为了优雅地退出程序,这时可以使用给一个全局变量记录是否接收到SIGINT信号,主程序每次进入循环时都会检查这个变量,如果发现进程接收到SIGINT,则释放资源优雅退出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李小白20200202

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值