linux 信号笔记

来源:互联网 发布:中国高速铁路 知乎 编辑:程序博客网 时间:2024/06/08 09:44

1.linux信号是一种古老的进程间通信的方式,唯一一种异步通信的方式,信号的默认处理方式一般是结束当前进程如SIGINT,SIGQUIT等,应用进程可以自己控制进程处理的方式和流程.
2.信号的注册 使用signal函数或者sigaction函数注册,
3.信号是不可靠的进程间通信方式,在信号的执行例程中不能被同一种信号打断,但是会被进程接收到的其他信号所打断,

#include <stdio.h>#include <signal.h>#include <stdlib.h>#include <unistd.h>void interrupt(int sig){    printf("Intertupt start\n");    sleep(3);    printf("Interrupt end\n");}void quit(int sig){    printf("quit start\n");    sleep(3);    printf("quit end\n");}int main(){    signal(SIGINT,interrupt);    signal(SIGQUIT,quit);    printf("Interrupt set for SIGINT\n");    sleep(10);    printf("Program NORMAL end\n");    return 0;}``

Interrupt set for SIGINT
^CIntertupt start
^CInterrupt end
Intertupt start
Interrupt end
Program NORMAL end

Interrupt set for SIGINT
^CIntertupt start
^\quit start
^\^\quit end
quit start
quit end
Interrupt end
Program NORMAL end

“`
第一种执行方式,在处理SIGINT信号时,发送一个SIGINT信号,进程需要等待到第一个信号的执行结束后,再继续执行第二个信号执行过程,
第二种执行方式,在处理SIGINT信号时,发送SIGQUIT信号给进程,进程需要转到SIGQUIT信号处理程序执行再返回,相当于嵌套的中断.
说明三,我们同时发送了两个SIGQUIT信号,但是却只执行了一次,说明信号是不可靠的通信方式,同一时间接收到的相同信号不会被保存下来,存在丢失的可能性.

3信号与系统调用
在执行系统调用的时候,进程接收到的信号一般不能打断系统调用的执行过程,而需要等待系统调用执行完毕才能执行对应的处理函数,. 但是当系统调用是慢速系统的时候就会被打断,如sleep,pause以及read write等系统调用.

4 kill 系统调用用于向指定的进程发送指定的信号,
int kill(int pid,int sig);
5 alarm 系统调用通知内核在执行 若干秒后发送SIGARLM信号该进程.fork()后在子进程中失效,在exec后有效,
信号处理方式在fork后有效,但是在exec后无效, 因为子进程的地址空间已经被覆盖,信号处理函数变得不可见.
6 setjump 和longjmp
当处理信号时有时候希望回到程序中以前的位置执行,这时候需要使用setjmp
保存跳回位置的上下文环境,然后再使用longjmp 执行跳回的动作.
int setjmp(jmp_buf env);
void longjmp(jmp_buf env,intval);

原创粉丝点击