信号
一。信号概念
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" ); } } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 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)