信号:进程收到信号并捕捉它做出响应(默认,自定义,忽略)
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<signal.h>
#include<string.h>
void sig_fun(int sig)自定义
{
printf("sig=%d\n",sig);sig=2,2是SIGINT的序号(它俩等价是一个宏定义)
}
int main()
{
signal(SIGINT,sig_fun);自定义语句(约定),如果产生SIGINT信号,则调用sig_fun函数,不写这行代码则按系统默认的(结束进程)
while(1)
{
printf("hello\n");
sleep(1);
}
}
void sig_fun(int sig)第一次打印sig,第二次使用系统默认的(终止进程)
{
printf("sig=%d\n",sig);
signal(sig,SIG_DFL);sig=2也就是SIGINT
}
signal(SIGINT,SIG_IGN)
忽略SIGINT信号
ctrl+\
也可以结束进程
让kill成为结束进程的命令的函数,这是两个参数的形式
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<signal.h>
int main(int argc,char* argv[])
{
kill 参数有两个,一个是进程的pid,另一个是信号类型sig
if(argv!=2)
{
printf("mykill arg err\n");
}
int pid=0;
sscanf(argv[1],"%d",&pid);将第一个参数转为整形并存在pid里
if(kill(pid,SIGINT)==-1)
{
printf("kill err\n");
}
}
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<signal.h>
int main(int argc,char* argv[])
{
kill 参数有两个,一个是进程的pid,另一个是信号类型sig
if(argv!=3)
{
printf("mykill arg err\n");
}
int pid=0;
int sig=0;
argv[0]存的是kill
sscanf(argv[1],"%d",&pid);将第一个参数转为整形并存在pid里
sscanf(argv[2],"%d",&sig);
if(kill(pid,sig)==-1)这是一个系统调用
{
printf("kill err\n");
}
}
9号
信号无法自定义,只能按照默认来结束进程
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<signal.h>
#include<sys/wait.h>
void sig_fun(int sig)这样既可以获取sig也可以防止父进程阻塞
{
printf("sig=%d\n",sig);
wait(NULL);还得用wait才不会成为僵死进程
}
int main()
{
int n=0;
char* s=NULL;
signal(SIGCHLD,sig_fun);子进程结束后会给父进程发SIGCHLD信号
//signal(SIGCHLD,SIG_IGN);直接忽略子进程也不会成为僵死进程
pid_t pid=fork();
assert(pid!=NULL);
if(pid==0)
{
s="child";
n=3;
}else
{
s="parent";
n=7;
}
for(int i=0;i<n;+=i)
{
printf("s=%s\n",s);
sleep(1);
}
exit(0);
}