信號是異步的,它會在程序的任何地方發生。由此程序正常的執行路徑被打破,去執行信號處理函數。一般情況下,進程正在執行某個系統調用,那麼在該系統調用返回前信號是不會被遞送的。但慢速系統調用除外,如讀寫終端、網絡、磁盤,以及wait和pause。這些系統調用都會返回-1,errno置爲EINTR。當系統調用被中斷時,我們可以選擇使用循環再次調用,或者設置重新啓動該系統調用(SA_RESTART)。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <signal.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
void int_handler (int signum)
{
printf ("int handler %d\n",signum);
}
int main(int argc, char **argv)
{
char buf[100];
ssize_t ret;
struct sigaction oldact;
struct sigaction act;
act.sa_handler = int_handler;
act.sa_flags=0;
act.sa_flags |= SA_RESTART;
sigemptyset(&act.sa_mask);
if (-1 == sigaction(SIGINT,&act,&oldact))
{
printf("sigaction failed!\n");
return -1;
}
bzero(buf,100);
ret = read(STDIN_FILENO,buf,10);
if (ret == -1)
{
printf ("read error %s\n", strerror(errno));
}
printf ("read %d bytes, content is %s\n",ret,buf);
sleep (10);
return 0;
}
^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
^Cint handler 2
hgfd
read 5 bytes, content is hgfd
把程序不用SA_RESTART:
結果
^Cint handler 2
read error Interrupted system call
read -1 bytes, content is
程序立即結束啦。
下面關於 kill(pid_t pid, 0):
雖然從函數的表面意思上看是殺死進程, 但是kill函數不單單只是殺死進程,而是對指定進程或進程組發送指定信號(SIGKILL, SIG).
函數原型如下:
int kill(pid_t pid, int sig);
pid > 0 向pid指定的進程發送sig指定的信號.
pid == 0 向調用kill函數所在進程組中的所以進程發sig指定的信號.
pid == -1 向調用kill函數所在進程擁有權限的所有進程發宋sig信號,除了進程1(init).
pid < -1 向進程組id 爲-pid 內的所有進程發送sig 信號.
返回值:成功返回0; 錯誤返回-1,並且errno會被設置相應的值.
如果sig == 0, 沒有信號發送,但是錯誤檢查還是會執行.sig=0, 可以被用於檢查pid指定的進程或進程組是否存在.
如下:
if(kill(mClientPid, 0) == -1 && errno == ESRCH){
printf("client process is dead!\n");
}
可以用命令行kill -l 查看所以信號
zhangpan-pc:/usr/include/c++/5.4.0$ 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
參考自:http://blog.chinaunix.net/uid-27801149-id-5774548.html
https://blog.csdn.net/gexiao/article/details/19488433
http://blog.csdn.net/ccccdddxxx/article/details/6308381