Linux 进程通信-信号的使用

2/10/2017来源:ASP.NET技巧人气:379

信号概念 信号(signal)是linux进程间通信的一种机制,全称为软中断信号,也被称为软中断。信号本质上是在软件层次上 对硬件中断机制的一种模拟。

信号由内核管理

产生的方式: 可以由内核自身产生,比如出现 硬件错误、内存读取错误,分母为0的除法等,内核需要通知相应进程。 也可以由其他进程产生并发送给内核,再由内核传递给目标进程。

什么信号不能捕捉也不能忽略? SIGKILL(终止进程) SIGSTOP (暂停进程)

kill -l // 查看系统支持的所有的信号

发送信号

$ kill -signal pid $ kill -9 1001 // 强制杀死1001进程

信号处理机制 可以用函数signal注册一个信号捕捉函数

#include<signal.h> typedefvoid(*sighandler_t)(int); //函数指针 sighandler_t signal(intsignum,sighandler_thandler);

signal 调用成功,返回处理函数的地址,否则返回SIG_ERR

#include<signal.h> #include<stdio.h> #include<unistd.h> void ouch(int sig){ PRintf("\nOUCH! - I got signal %d\n",sig); // 恢复终端中信号的默认行为 (void) signal(SIGINT,SIG_DFL); } int main(){ // 改变终端终端信号SIGINT的默认行为,执行ouch // 而不是终止程序的执行 (void) signal(SIGINT,ouch); while(1) { printf("hello world!\n"); sleep(1); } return 0; }

进程的四种状态 RSTZ T:暂停

sigaction信号处理机制

3.1 信号情况处理分析 注册信号处理函数 当注册信号函数正在处理时,来了同类信号排队执行 当注册信号函数正在处理时,捕捉到其他类信号,打断然后先执行其他类信号, 如果在发生信号时,程序正阻塞在某个系统调用,例如调用 read()函数,则在处理完毕信号后,接着从阻塞的系统返回。如 果不指定该参数,中断处理完毕之后,read函数读取失败。

#include<signal.h> int sigaction(int sig,const struct sigaction *act,struct sigaction *oact); 这个函数和signal 函数一样,用于设置与sig关联的动作。而oact不为空的话,它会保存原来的signal的位置。act则用于设置指定信号的动作。

#include<signal.h> #include<stdio.h> #include<unistd.h> void ouch(int sig){ printf("\nOUCH! - I got signal %d\n",sig); } int main(){ struct sigaction act; act.sa_handler=ouch; // 创建空的信号屏蔽字,即不屏蔽任何信息 sigemptyset(&set.sa_mask); // 使sigaction函数重置默认行为 act.sa_flags=SA_RESETHAND; sigaction(SIGIN,&act,0); while(1){ printf("Hello world:\n"); sleep(1); } return 0; }

3.2.sigaction信号处理注册 函数原型: #include<signal.h> int sigaction(int signum,const struct siginfo_t *act ,struct sigaction *oldact)

struct sigaction{ void(*sa_handler)(int); //老类型的信号处理函数指针 void(*sa_sigaction)(int,siginfo_t*,void*);//新类型的信号处理函数指针 sigset_tsa_mask; //将要被阻塞的信号集合 intsa_flags; //信号处理方式掩码(SA_SIGINFO) void(*sa_restorer)(void); //保留,不要使用 };

sa_handler 和 sa_sigaction 只能一个生效

sa_flags