SIGCLD信号及配合wait的使用

本文介绍了SIGCHLD和SIGCLD信号的使用场景及处理方式,详细解释了这两种信号如何帮助父进程管理子进程的状态变化,尤其是在避免僵尸进程方面的作用。并通过一个具体的示例展示了如何通过注册信号处理函数来响应子进程的状态改变。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SIGCHLD的语义为:子进程状态改变后产生此信号,父进程需要调用一个wait函数以确定发生了什么。
对于SIGCLD的早期处理方式如下:

  • 1、如果进程特地设置该信号的配置为SIG_IGN,则调用进程的子进程将不产生僵死进程。
  • 2、如果将SIGCLD的配置设置为捕捉,则内核立即检查是否有子进程准备好被等待,如果是这样,则调用SIGCLD处理程序。

一般的,父进程在生成子进程之后会有两种情况,一种是父进程继续去做别的事情,另一种是父进程啥都不做,一直在wait子进程退出.
SIGCHLD信号就是为这第一种情况准备的,它让父进程去做别的事情,而只要父进程注册了处理该信号的函数,在子进程退出时就会调用该函数,在该函数中又可以调用wait得到终止的子进程的状态。处理信号的函数执行完后,再继续做父进程的事情.
也就是说,如果父进程在fork之后调用wait,就会阻塞,直到有一个子进程退出。
如果父进程在fork之前先signal(SIGCLD, sig_cld),即注册了SIGCLD的信号处理函数。然后做自己的事情。当子进程退出时,会给父进程发送一个SIGCLD信号。然后sig_cld函数就会执行。可以在sig_cld函数中调用wait获得子进程退出时的状态,并且此时wait不会阻塞。 当sig_cld函数执行完后,父进程又继续做自己的事情。
下面放一个apue上的例子:

#include    "apue.h"
#include    <sys/wait.h>

static void    sig_cld(int);

int
main()
{
    pid_t    pid;

    if (signal(SIGCLD, sig_cld) == SIG_ERR)
        perror("signal error");
    if ((pid = fork()) < 0) {
        perror("fork error");
    } else if (pid == 0) {        /* child */
        sleep(2);
        _exit(0);
    }

    pause();    /* parent */
    exit(0);
}

static void
sig_cld(int signo)    /* interrupts pause() */
{
    pid_t    pid;
    int        status;

    printf("SIGCLD received\n");

    if (signal(SIGCLD, sig_cld) == SIG_ERR)    /* reestablish handler */
        perror("signal error");

    if ((pid = wait(&status)) < 0)        /* fetch child status */
        perror("wait error");

    printf("pid = %d\n", pid);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值