Linux 进程间通信之信号通信 –

本文参考了:

http://blog.csdn.net/yikai2009/article/details/8643818

http://blog.chinaunix.net/uid-1877180-id-3011232.html

sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作)。

他是POSIX的信号接口,而signal()是标准C的信号接口(如果程序必须在非POSIX系统上运行,那么就应该使用这个接口)

给信号signum设置新的信号处理函数act, 同时保留该信号原有的信号处理函数oldact

intsigaction(int signo,conststructsigaction*restrict act,

structsigaction*restrict oact);

1、其中signo的选择有许多:

信号处理:

一、忽略此信号;(但SIGKILL和SIGSTOP信号不可被忽略)

二、执行用户希望的动作;(调用一个用户函数,执行用户希望的处理)

三、执行系统默认动作;(对大多数信号的系统默认动作是终止进程)

信号发送:(主要函数有kill和raise)

区别:

kill既可以向自身发送信号,也可以向其他进程发送信号,raise是向进程自身发送信号。

int kill(pid_t pid, int signo)

int raise(int signo)

alarm方式发送:

使用alarm函数可以设置一个时间值,当所设置的时间到了时,产生SIGALRM信号。如果不捕捉此信号,则默认动作是终止此进程。

unsigned intalarm(unsigned int seconds)

seconds:经过了指定的seconds秒后会产生SIGALRM

pause函数:

使调用进程挂起,直至捕捉到一个信号。

int pause(void)

只有执行了一个信号处理函数后,挂起才结束

可以使用kill命令发

kill-s SIGINT 1234或kill -s SIGQUIT 1234(其中1234是进程的pid)

也可以按Ctrl + C(SIGINT信号)或者Ctrl + \(SIGQUIT信号)

2、其中结构sigaction定义如下:

structsigaction{void (*sa_handler)(int); sigset_t sa_mask;int sa_flag;void (*sa_sigaction)(int,siginfo_t*,void*);};

sa_handler字段包含一个信号捕捉函数的地址

sa_mask字段说明了一个信号集,在调用该信号捕捉函数之前,这一信号集要加进进程的信号屏蔽字中。仅当从信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值。

sa_flag是一个选项,主要理解两个

SA_INTERRUPT 由此信号中断的系统调用不会自动重启SA_RESTART 由此信号中断的系统调用会自动重启

SA_SIGINFO 提供附加信息,一个指向siginfo结构的指针以及一个指向进程上下文标识符的指针

最后一个参数是一个替代的信号处理程序,当设置SA_SIGINFO时才会用他。

例子:

#include <stdio.h>#include <signal.h>#include <unistd.h>void show_handler(int sig){ printf("I got signal %d\n", sig); int i; for(i = 0; i < 5; i++) { printf("i = %d\n", i); sleep(1); }}int main(void){ int i = 0; struct sigaction act, oldact; act.sa_handler = show_handler; sigaddset(&act.sa_mask, SIGQUIT); //见注(1) act.sa_flags = SA_RESETHAND | SA_NODEFER; //见注(2) //act.sa_flags = 0; //见注(3) sigaction(SIGINT, &act, &oldact); while(1) { sleep(1); printf("sleeping %d\n", i); i++; }}注:(1) 如果在信号SIGINT(Ctrl + c)的信号处理函数show_handler执行过程中,本进程收到信号SIGQUIT(Crt+\),将阻塞该信号,直到show_handler执行结束才会处理信号SIGQUIT。

(2) SA_NODEFER 一般情况下, 当信号处理函数运行时,内核将阻塞<该给定信号 — SIGINT>。但是如果设置了SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号。 SA_NODEFER是这个标记的正式的POSIX名字(还有一个名字SA_NOMASK,为了软件的可移植性,一般不用这个名字) SA_RESETHAND 当调用信号处理函数时,将信号的处理函数重置为缺省值。 SA_RESETHAND是这个标记的正式的POSIX名字(还有一个名字SA_ONESHOT,为了软件的可移植性,一般不用这个名字)

(3) 如果不需要重置该给定信号的处理函数为缺省值;并且不需要阻塞该给定信号(无须设置sa_flags标志),那么必须将sa_flags清零,否则运行将会产生段错误。但是sa_flags清零后可能会造成信号丢失!

谁的指间滑过了千年时光;谁在反反复复中追问可曾遗忘;

Linux 进程间通信之信号通信 –

相关文章:

你感兴趣的文章:

标签云: