信号是Linux系统下的异步处理机制,对于应用程序来说异步事件是不可预知的。Linux信号在实现上是一种软中断,可以导致正在运行的进程被异步打断,转而处理一个突发事件。
常见信号:
(1)SIGCHLD。子进程退出时会给父进程发送该进程。父进程可以根据该信号来完成对子进程PCB资源的回收。
(2)SIGKILL和SIGSTOP不能被屏蔽、安装,即用户不能自定义这两个信号的处理。
(3)SIGSTOP和SIGCONT是配对的。一个进程在收到SIGSTOP后会暂停执行,进入暂停状态,并屏蔽除SIGKILL所有信号。当该进程收到SIGCONT会继续执行。
(信号可以唤醒进入阻塞状态的进程。)
Linux信号(kill -l):
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2
37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6
41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10
45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14
49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8
57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4
61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
信号基本概念:
发送信号、安装信号(设置信号到来时执行的操作)、递送信号、捕获信号、屏蔽信号(如果一段时间后解除屏蔽,该信号将会被捕捉到)、忽略信号(目标进程直接丢弃信号)、未决信号、可靠信号与不可靠信号。
发送信号:
#include<signal.h>
/*向指定进程发送信号*/
int kill(__pid_t __pid,int __sig);
/*给当前进程发送一个信号*/
int raise(int __sig);
/*给当前进程定时发送信号*/
unsigned int alarm(unsigned int __seconds)
/*与alarm类似,第一个信号发送时间可以指定*/
__useconds_t ualarm(__useconds_t __value,__useconds_t __interval)
/*定时器高级应用*/
int gettitimer(int which,struct itimerval *value)
杀死指定进程:
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char **argv){
int pid;
if(argc!=2){
printf("Usage:%s pid\n",argv[0]);
return -1;
}
pid=atoi(argv[1]);
while(kill(pid,9))
printf("killing %d\n",pid);
printf("ok\n");
return 0;
}
安装信号:
/安装信号,不推荐使用/
__sighandler_t signal(int __sig,__sighandler_t __handler)
/安装信号,获得上次的安装信息/
int sigaction(int __sig,struct sigaction *__act,struct sigaction *__oact)
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
void sig_usr(int);
int main(int argc,char **argv){
if(signal(SIGUSR1,sig_usr)==SIG_ERR){
printf("can not catch SIGUSR1\n");
return -1;
}
if(signal(SIGUSR2,sig_usr)==SIG_ERR){
printf("can not catch SIGUSR1\n");
return -1;
}
while(1){
sleep(1);
printf("biu biu biu\n");
raise(SIGUSR1);
}
return 0;
}
void sig_usr(int sig){
if(sig==SIGUSR1){
printf("SIG1\n");
}
else if(sig==SIGUSR2){
printf("SIG2\n");
}
}
信号集:
因为一个进程有可能屏蔽多个信号,为了便于管理,Linux使用信号集来管理多个信号。涉及到的函数较多,API暂不列出。