信号通常用来向一个进程通知事件,是异步的,接收信号的进程没有控制权。
SIGKILL、SIGSTOP信号是不可捕捉的。
1、发送信号
int kill(pid_t pid, int sig) //参数pid指定一个进程, sig是要发送的信号
int raise(int signo)
raise(signo) 等价于 kill(getpid(),signo)。kill函数将信号发送给进程,raise函数允许进程向自身发送信号。
unsigned int alarm(unsigned int seconds);//一个进程只能设置一次超时
void abort(void);
unsigned int sleep(unsigned int seconds);
下面是signal的例子,不过现在不提倡用signal,因为在信号未决的情况下,用signal可能会出现问题。
void catch_Signal(int Sign)
{
switch(Sign)
{
case SIGINT:
printf("SIGINTSignal\n");
exit(0); ////SIGINT来了后,进程退出
case SIGALRM:
printf("SIGALRMSignal\n");
exit(0);
case SIGKILL:
printf("SIGKILLSignal\n");
break;
case SIGTERM:
printf("SIGTERMSignal\n");
break;
}
}
int main(int arg, char *args[])
{
printf("SIGINT =%d, SIGALRM = %d\n", SIGINT, SIGALRM);
signal(SIGINT,catch_Signal); //SIGINT:用户按Ctrl+C,捕获该信号
signal(SIGALRM,catch_Signal);//若此句注释掉,则SIGALRM默认退出
signal(SIGKILL,catch_Signal);
signal(SIGTERM,catch_Signal);//这四个signal函数只是登记下,告诉操作系统信号来了后要执行
//raise(SIGPIPE);//执行此函数,直接停止
int i = 0;
alarm(5);
while(1)
{
scanf("%d", &i);
pause();
printf("hello:%d\n", i++);
}
return EXIT_SUCCESS;
}
2、改进的捕获信号
sigaction函数的功能是检查或修改与指定信号相关联的处理动作,该函数取代signal函数。
下面是用sigaction函数封装成自己的signal函数,这样和signal用法一样:
int mysignal(int signo, void (*func)(int))
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
return sigaction(signo, &act, &oact);
}
这样,1中代码所有的signal都可以改为mysignal。
3、自定义信号
例子如下://通过自定义的SIGUSR1信号,执行mykill [pid],激活sign.c中的操作
sign.c文件下:
int status = 0;
void catch_Signal(int Sign)
{
switch(Sign)
{
case SIGINT:
printf("SIGINTSignal\n");
exit(0); //SIGINT来了后,进程退出
case SIGALRM:
printf("SIGALRMSignal\n");
alarm(5);
break;
case SIGUSR1:
status = 1;
break;
}
}
int mysignal(int signo, void (*func)(int))
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
return sigaction(signo, &act, &oact);
}
int main(int arg, char *args[])
{
printf("SIGINT =%d, SIGALRM = %d\n", SIGINT, SIGALRM);
mysignal(SIGINT, catch_Signal); //SIGINT:用户按Ctrl+C,捕获该信号
mysignal(SIGALRM, catch_Signal);
mysignal(SIGUSR1, catch_Signal);
int i = 0;
while(1)
{
if(status == 1)
printf("hello:%d\n", i++);
sleep(1);
}
return EXIT_SUCCESS;
}
mykill.c文件下:
int main(int arg, char *args[])
{
if(arg > 1)
{
int pid = atoi(args[1]);
kill(pid, SIGUSR1);
}
return EXIT_SUCCESS;
}