Linux signals理论、C语言捕获信号及处理
首先需要知道signals和interrupt是不同的。
signal属于进程通信机制的一种实现方式
(还有的实现为:Pipes、Sockets
其中Sockets又可分为: System V IPC Mechanisms、Message Queues、Semaphores、Shared Memory)
而具体的不同,别人的回答是:
Interrupts can be viewed as a mean of communication between the CPU and the OS kernel. Signals can be viewed as a mean of communication between the OS kernel and OS processes.
Interrupts may be initiated by the CPU (exceptions -e.g.: divide by zero, page fault), devices (hardware interrupts -e.g.: input available), or by a CPU instruction. They are eventually managed by the CPU, which “interrupts” the current task,and invokes an 0S-kernel provided ISR/interrupt handler
Signals may be initiated by the OS kernel(下面的实例也揭示了这一点), or by a process( kill() ). They are eventually managed by the OS kernel, which delivers them to the target thread/process, invoking either a generic action (ignore, terminate, terminate and dump core) or a process-provided signal handler.
SIGKILL与SIGSTOP是两个唯一不能忽略也不能捕获的信号C语言捕获信号并处理
第一步:向内核注册
the process has to register a signal handling function to the kernel.
原型是:c void (int sig)
第二步:获得signal handler
To get the signal handler function registered to the kernel, the signal handler function pointer is passed as second argument to the ‘signal’ function
原型是:c void (*signal(int signo, void (*func )(int)))(int);
简单化:c sigfunc *signal(int, sigfunc*);
实例一:简单捕获信号并处理
#include #include #include void sig_handler(int signo) { if (signo == SIGINT) printf("received SIGINT\n"); } int main(void) { if (signal(SIGINT, sig_handler) == SIG_ERR) printf("\ncan't catch SIGINT\n"); //必须加上死循环(或者用挂起)来让信号能被进程接收 while(1) sleep(1); return 0; } //注意,当前终端用ctrl+c模拟, //需要终止时,另一个终端使用 ps aux查看进程号,然后用 kill -9 进程号 //来杀死
还值得一提的是,这儿用while(1) sleep(1)
比用单纯的while死循环要好,因为直接while可能会消耗cpu的大部分资源,导致电脑很慢。
On a side note, the use of function sleep(1) has a reason behind. This function has been used in the while loop so that while loop executes after some time (ie one second in this case). This becomes important because otherwise an infinite while loop running wildly may consume most of the CPU making the computer very very slow
实例二:自定义信号
#include #include #include void sig_handler(int signo) { if (signo == SIGUSR1) printf("received SIGUSR1\n"); else if (signo == SIGKILL) printf("received SIGKILL\n"); else if (signo == SIGSTOP) printf("received SIGSTOP\n"); } int main(void) { if (signal(SIGUSR1, sig_handler) == SIG_ERR) printf("\ncan't catch SIGUSR1\n"); if (signal(SIGKILL, sig_handler) == SIG_ERR) printf("\ncan't catch SIGKILL\n"); if (signal(SIGSTOP, sig_handler) == SIG_ERR) printf("\ncan't catch SIGSTOP\n"); // A long long wait so that we can easily issue a signal to this process while(1) sleep(1); return 0; }
另一个终端运行:
$ kill -USR1 进程号
输出:
$ ./sigfunc can't catch SIGKILL can't catch SIGSTOP received SIGUSR1
上一篇: 在用户离开页面时提示信息