信号是提供异步事件处理机制的软件中断。
信号的处理:
忽略:什么也不做,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子进程
没有子进程了!