信号的忽略、默认、捕获操作和太平间信号

本文介绍了信号在软件中作为异步事件处理的机制,包括忽略、默认和捕获信号的处理方式。通过C语言实例展示了如何捕获和处理2号信号,并探讨了17号信号(子进程终止信号)的处理,如子进程回收的信号处理函数sigchild。
摘要由CSDN通过智能技术生成

信号是提供异步事件处理机制的软件中断。
信号的处理:
忽略:什么也不做,SIGKILL(9)和SIGSTOP(19)不能被忽略
默认:在没有人为设置的情况,系统缺省的处理行为
捕获:接收到信号的进程会暂时执行,转而执行一端事先编写好的处理
代码,执行完毕后再从暂停执行的地方继续运行。

//信号的处理
#include<stdio.h>
#include<unistd.h>
#include<signal.h>

typedef void (*sighandler_t)(int);
//信号处理函数
void sigfun(int signum)
{
    printf("%d进程:捕获到%d信号\n",getpid(),signum);
}
int main()
{
    //忽略2号信号
    sighandler_t ret = signal(2,SIG_IGN);
    if(ret == SIG_ERR)
    {
        perror("signal");
        return -1;
    }
    printf("ret=%p\n",ret);
    //捕获2号信号
    ret = signal(2,sigfun);
    if(ret == SIG_ERR)
    {
        perror("signal");
        return -1;
    }
    printf("ret=%p\n",ret);
    //恢复默认的2号信号
    ret = signal(2,SIG_DFL);
    if(ret == SIG_ERR)
    {
        perror("signal");
        return -1;
    }
    while(1);
    return 0;
}

太平间信号:(17)号信号
子进程终止发送的信号,

//太平间信号
#include<stdio.h>
#include<sys/wait.h>
#include<unistd.h>
#include<signal.h>
#include<stdlib.h>
#include<errno.h>
//信号处理函数,完成收尸
void sigchild(int status)
{
    //在信号处理函数执行期间,如果有多个信号到来,只保留1个信号,其余信号会丢失
    printf("%d进程捕获到%d信号\n",getpid(),status);
    sleep(3);
    while(1)
    {
        //pid_t wait_pid = wait(NULL);
        pid_t wait_pid = waitpid(-1,NULL,WNOHANG);
        if( wait_pid == -1)
        {   if(errno == ECHILD)
            {
                printf("没有子进程了!\n");
                break;
            }
            perror("wait");
            exit(-1);
        }
        else if(wait_pid == 0)
        {
            printf("子进程在运行\n");
            break;
        }
        else
        {
            printf("%d进程:回收了%d子进程\n",getpid(),wait_pid);
        }
    }
}

int main()
{
    //对17号信号进行捕获
    if(signal(17,sigchild) == SIG_ERR)
    {
        perror("signal");
        return -1;
    }
    //创建多个子进程
    for(int i = 0 ; i < 5 ; i++)
    {
        pid_t pid = fork();
        if(pid == -1)
        {
            perror("fork");
            return -1;
        }
        if(pid == 0)
        {
            printf("%d进程:我是子进程\n",getpid());
            sleep(1);
            return 0;
        }
    }
    //创建一直不退出进程的老六
    pid_t six = fork();
    if(six == -1)
    {
        perror("fork");
        return -1;
    }
    if(six == 0)
    {
        printf("我是老六\n");
        sleep(15);
        return 0;
    }
    //printf("你别
    //管我!\n");
    while(1);
    return 0;
}

121414进程:我是子进程
121416进程:我是子进程
121418进程:我是子进程
121415进程:我是子进程
121417进程:我是子进程
我是老六
121413进程捕获到17信号
121413进程:回收了121414子进程
121413进程:回收了121415子进程
121413进程:回收了121416子进程
121413进程:回收了121417子进程
121413进程:回收了121418子进程
子进程在运行
121413进程捕获到17信号
子进程在运行
121413进程捕获到17信号
121413进程:回收了121419子进程
没有子进程了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值