linux进程篇 (三) 进程间的通信2 信号通信
用户空间 进程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系统默认 自定义 */
例子:
1.kill 自己写一个杀死进程函数
#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; }