用戶空間 進程A <----沒法通訊----> 進程B -----------------|--------------------------------------|-------------- | | 內核空間 |<-------------> 信號 <--------------->| ---------------------------------------------------------------------- (1) 信號的發送 kill raise alarm (2) 信號的接收 pause sleep while (3) 信號的處理 signal 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 發什麼信號(64) 發給誰(pid)
#include <signal.h> #include <sys/types.h> // 發送 int kill(pid_t pid, int sig); int raise(int sig); //發信號給本身 == kill(gitpid(),sig) #include <unistd.h> unsigned alarm(unsigned seconds); //接收 while(); sleep(); int pause(void); //成功0 失敗-1 進程狀態爲S。 //處理 #include <signal.h> void (*signal(int sig, void (*func)(int)))(int); //or in the equivalent but easier to read typedef'd version: typedef void (*sig_t) (int); sig_t signal(int sig, sig_t func);
int kill(pid_t pid, int sig); /*pid 正數 要接收信號的pid 0 信號發送到和pid同一個進程組的進程 -1 信號發送給全部進程表的進程 返回值: 0成功 -1失敗 */
int raise(int sig); //發信號給本身 == kill(gitpid(),sig) //raise(9) == _exit(),不輸出緩存,直接消亡
#include <unistd.h> unsigned alarm(unsigned seconds); //和raise同樣 只發送信號給本身,延遲一段時間後發送 //發送鬧鐘信號的函數 默認處理是終止進程
void (*signal(int sig, void (*func)(int)))(int); //or in the equivalent but easier to read typedef'd version: typedef void (*sig_t) (int); sig_t signal(int sig, sig_t func); //分析void (*signal(int sig, void (*func)(int)))(int); void (*func)(int) //函數指針,返回值viod, 1個int參數 -> A signal(int sig, A) 因此 signal 返回的就是一個函數指針, void (*P)(int); //一個帶 int參數,返回值爲void的函數指針 //P== signal(int sig, A) 因此 signal 返回的就是一個函數指針, typedef void (*sig_t) (int); //整個函數有2個地方能夠替換 sig_t signal(int sig, sig_t func)
typedef void (*sig_t) (int); sig_t signal(int sig, sig_t func) /* 1,處理什麼信號 2,怎樣處理這個信號 SIG_IGN 忽視該信號 SIG_DFL系統默認 自定義 */
例子:linux
1.kill 本身寫一個殺死進程函數git
#include <stdio.h> #include <string.h> #include <signal.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> int main(int argc, char const *argv[]) { /*kill 並不是殺死進程 kill 9 pid 纔是殺死一個進程,kill是信號通訊的框架。 * 下面將搭建kill 信號通訊的框架 */ int sig,pid; int ret; if(argc < 3){ puts("請輸入正確的參數 !"); return -1; } sig = atoi(argv[1]); pid = atoi(argv[2]); printf("sig = %d, pid = %d\n", sig,pid); ret = kill(pid,sig); if(ret < 0){ perror("kill"); return -2; } return 0; }
2.signal 信號處理緩存
#include <stdio.h> #include <string.h> #include <signal.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> //wait調用相關函數庫 #define CHLD 20 //mac CHLD是20,linux 是17 void sig_fun1(int signum){ int i; while(i < 10){ printf("sig fun ,signum is %d,i =%d\n",signum,i); i++; sleep(1); } return; } void sig_exit(int signum){ printf("recv sig %d",signum); wait(0); return; } int main(int argc, char const *argv[]) { pid_t pid; pid = fork(); if(pid > 0){ //子進程 int i; signal(10,sig_fun1); signal(CHLD,sig_exit); while(i < 20){ printf("我是子進程,i = %d\n",i); i++; sleep(1); } }else{ //父進程 sleep(10); puts("我是子進程"); kill(getppid(),10); exit(0); } return 0; }