信号

一。信号概念

1.1信号基本概念

 1.2产生信号的5种方式

1.3信号的状态和处理方式

1.4信号的四要素

编号 

名称 

事件

默认处理动作(Term终止 Ign忽略 Core终止生成core文件 Stop暂停 Cont继续)

 

   

      

1.5kill函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<stdio.h>
#include<sys/types.h>
#include<signal.h>
#include<unistd.h>
int main()
{
        int ret=kill(getpid(),SIGKILL);
        if(ret==-1)
        {
                perror("kill err");
                return 0;
        }
        return 0;
}

1.6raise和abort

1.7alarm函数

1.8setitimer

it_interval表示下次定时的时间间隔,it_value表示定时的时常

tv_sec 表示秒 ,tv_usec表示毫秒

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
//第一次10.5s,之后每隔3s触发SIGALRM信号 <br>//signal捕捉信号<br>//#include <signal.h><br>//typedef void (*sighandler_t)(int);<br>//sighandler_t signal(int signum, sighandler_t handler);<br><br>#include<stdio.h>
#include<unistd.h>
#include<sys/time.h>
#include<signal.h>
void fun(int sign)
{
        printf("SIGALRM TRIGGRED……\n");
}
int main()
{
        signal(SIGALRM,fun);
        struct itimerval newtime;
        struct itimerval oldtime;
        //设置定时时常为10s 5000ms
        newtime.it_value.tv_sec=10;
        newtime.it_value.tv_usec=500;
        //下次时间隔0
        newtime.it_interval.tv_sec=3;
        newtime.it_interval.tv_usec=0;
        int ret=setitimer(ITIMER_REAL,&newtime,&oldtime);
        if(ret==-1)
        {
                perror("setitimer err:");
                return 0;
        }
        while(1);
        return 0;
}

二。信号集操作

1.未决信号集和阻塞信号集

 

2.设定信号集的状态

3.sigprocmask函数

3.1 函数原型

 

3.1sigprocmask函数将自定义的信号集来设置阻塞信号集(根据SIG_BLOCK,SIG_UNBLOICK,SIG_SETMASK不同)

 

 4.sigpending函数

 

 5.打印未决信号集

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
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
void printped(sigset_t *ped)
{
        int i;
        for(i=1;i<32;i++)
        {
                if(sigismember(ped,i))
                {
                        printf("1");
                }else
                        printf("0");
        }
        printf("\n");
}
int main()
{
 
        sigset_t myset,oldset,ped; //自定义信号集,保存改变前的阻塞信号集,保存未决信号集
        sigemptyset(&myset); //初始化自定义信号集
        sigaddset(&myset,SIGQUIT); //设置信号屏蔽
        sigaddset(&myset,SIGINT);
        sigaddset(&myset,SIGTSTP);
        sigaddset(&myset,SIGKILL);  //SIGKILL不能被设置为屏蔽
        sigprocmask(SIG_BLOCK,&myset,&oldset); //通过自定义信号集和SIG_BLOCK设置阻塞
        while(1)
        {
                sigpending(&ped);   //传出未决信号集
                printped(&ped);  //打印
                sleep(5);
        }<br>      return 0;<br>}

三.信号捕捉

1.signal函数

sighandler_t 为返回值为void,参数为int的函数指针

2.sigaction函数

2.1函数原型

2.2 sigacntion捕捉信号代码

复制代码
 1 #include<stdio.h>
 2 #include<signal.h>
 3 #include<unistd.h>
 4 void fun(int sign)
 5 {
 6         printf("%d signal is catched\n",sign);
 7 }
 8 int main()
 9 {
10         struct sigaction act,oldact;
11         act.sa_handler=fun; //设置信号捕捉函数
12         sigemptyset(&act.sa_mask); //初始化掩码
13         sigaddset(&act.sa_mask,SIGQUIT);//设置屏蔽信号
14     act.sa_flags=0; //默认属性,信号捕捉函数执行时。自动屏蔽本信号 
15     int ret=sigaction(SIGINT,&act,&oldact); 
16     if(ret==-1) 
17     { perror("signaction err"); 
18     return 0; 
19     } 
20     while(1); 
21 }
复制代码

 

2.3 信号捕捉特性(在信号捕捉函数执行时被屏蔽的信号,只执行一次)

 

四。SIGCHLD信号

1.SIGCHLD信号在子进程结束时发出,可以通过捕获SIGCHLD信号来回收子进程

2。代码示例

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
49
50
51
52
53
54
55
56
57
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<signal.h>
#include<sys/types.h>
 
void catch_sig(int num)
{
    pid_t wpid;
    while((wpid=waitpid(-1,NULL,WNOHANG))>0)
    {
        printf("wait child %d sucess\n",wpid); //每次接收信号回收所有能回收的子进程
    }
    return ;
}
int main()
{
    int i=0;
    pid_t pid;
    //在创建子进程之前屏蔽SIGHLD信号
    sigset_t myset,oldset;
    sigemptyset(&myset);
    sigaddset(&myset,SIGCHLD);
    //oldsset保留现场,设置了SIGCHLD阻塞信号集
    sigprocmask(SIG_BLOCK,&myset,&oldset);
    for(i =0;i<10;i++)
    {
        pid=fork();
        if(pid == 0)
        {
            break;
        }
    }  
    if(i==10){
        sleep(20); //模拟注册信号晚于子进程结束
        struct sigaction act;
        act.sa_flags=0;
        sigemptyset(&act.sa_mask);
        act.sa_handler = catch_sig;
        int ret=sigaction(SIGCHLD,&act,NULL);
        if(ret==-1)
        {
            perror("sigaction err");
            return 0;
        }
        //解除屏蔽
        sigprocmask(SIG_SETMASK,&oldset,NULL);     
        while(1)
        {      
            sleep(1);
        }
    }else if(i<10){
        printf("I am %d child , pid= %d \n",i,getpid());
        //  sleep(i);
    }  
 
}

六。pause函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
 
 
void catchSig(int sign)
{
        printf("catch alarmw");
}
int mysleep(unsigned int sec)
{
        signal(SIGALRM,catchSig);
        alarm(sec);
        int ret=pause();<br>     if(ret==-1&&errno==EINTR)<br>      {<br>        printf("pause sucess");<br>        }<br>
        return 0;
}
int main()
{
        while(1){
                mysleep(1);
                printf("----------------------\n");
        }
}

  

posted @   荼离伤花  阅读(368)  评论(0编辑  收藏  举报
编辑推荐:
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· 程序员常用高效实用工具推荐,办公效率提升利器!
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
点击右上角即可分享
微信分享提示