【C/C++】多进程:信号量的监听与处理函数

本文介绍了C/C++中如何使用signal()函数处理wait()阻塞问题。通过signal()监听SIGSTOP、SIGCHLD、SIGWINCH信号,实现异步回调,使得父进程在执行其他任务时仍能及时处理子进程状态变化。示例代码展示了信号处理函数的注册和执行过程。
摘要由CSDN通过智能技术生成

文章结构:


wait()的阻塞问题

  之前的多进程:父进程监听子进程状态 wait()的使用文章中,父进程为了获取子进程的SIGSTOP、SIGTERM等信号时,由于调用了wait而导致主进程一直阻塞。在实际的开发中,主进程在等待子进程状态变化时还会有其它的事情要去执行,所以需要一种异步回调机制,让主进程可以在执行其它任务的时候,又可以监听到子进程的进程状态变化时及时处理。

  signal()函数就可以解决以上的问题。


signal()函数讲解

  signal()函数原型如下:

   #include <signal.h>

   typedef void (*sighandler_t)(int);
   sighandler_t signal(int signum, sighandler_t handler);

  typedef定义了一类函数名叫sighandler_t,该函数返回类型为void,且只有一个int型参数。

  signal()函数第一个参数signum指所要监听的进程状态的变量信号,所有可监听的信号量的定义可以从sys/signal.h头文件中去查阅。本文文章的demo中要处理的信号量有:

SIGSTOP: 发送给父进程的,表示子进程被外部命令所暂停。命令可以是kill,也可以在top中操作。

SIGCHLD: 发送给父进程的,表示子进程被外部命令所暂停或已经执行完毕退出。这时需要父进程执行wait函数让子进程从僵尸进程状态彻底被系统回收。

SIGWINCH: 程序窗口大小发生变化。在终端命令行下运行可执行文件时鼠标拖动一下窗口即可获得此信号。

  signal()函数第二个参数是指定signum的处理函数。该函数的唯一参数将会被赋值为被监听到的信号量。在此函数中可以调用wait或其它处理逻辑。也可以赋值为系统的SIG_IGNSIG_DFL函数,分别表示忽略和默认处理方式。但是信号量SIGKILLSIGSTOP的处理方式是不能被忽略处理。

  当自定义了信号量处理函数后,所监听的信号被捕获,则该信号会被设置为阻塞blocked,然后再执行处理函数中的逻辑,处理函数执行完毕后,信号量恢复为未阻塞状态unblocked

  signal()函数正常执行,返回值为signum的原有处理函数;否则出错返回SIG_ERR,并且可以通过errno来查看错误原因。

  signal()函数在不同的Unix或Linux版本间存在较大的差异,所以一般推荐用sigaction()函数来替换。本文不涉及sigaction()的内容。


示例代码

  接下来演示signal()函数的使用。代码示例中依然用到了对标准输出流的重定向freopen,将子进程的日志输出到child_signal.txt,父进程日志输出到main_signal.txt中去。

signal.c

      
      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值