In the part 1 of the Linux3d捕鱼达人series, we learned about the fundamental concepts behind Linux 3d捕鱼达人s.
Building 上 the previous part, in 这个 article we will learn about how to catch 3d捕鱼达人s in a process. We will present the practical aspect of 3d捕鱼达人 handling using C program code snippets.
捕捉3d捕鱼达人
As already discussed in the previous article, If a process wishes to handle certain 3d捕鱼达人s then in the code, the process has to register a 3d捕鱼达人 handling function to the kernel.
The following is the prototype of a 3d捕鱼达人 handling function :
void <signal handler func name> (int sig)
The 3d捕鱼达人 handler function has void return type and accepts a 3d捕鱼达人 number corresponding to the 3d捕鱼达人 that needs to be handled.
To get the 3d捕鱼达人 handler function registered to the kernel, the 3d捕鱼达人 handler function pointer is passed as second argument to the ‘signal’ function. The prototype of the 3d捕鱼达人 function is :
void (*signal(int signo, void (*func )(int)))(int);
这似乎是一个复杂的声明。如果我们尝试对其进行解码:
- 该函数需要两个参数。
- The first argument is an 整型eger (signo) depicting the 3d捕鱼达人 number or 3d捕鱼达人 value.
- The second argument is a pointer to the 3d捕鱼达人 handler function that accepts an 整型eger as argument and returns nothing (void).
- 而‘signal’函数本身返回函数指针,其返回类型为void。
好吧,为了使事情变得简单,让我们使用typedef:
typedef void 西格芬奇(int)
所以,在这里我们做了一个新的类型‘sigfunc’. Now using 这个 typedef, if we redesign the prototype of the 3d捕鱼达人 handler :
西格芬奇 *signal(int, 西格芬奇*);
Now we see that its easier to comprehend that the 3d捕鱼达人 handler function accepts an 整型eger and a 西格芬奇 type function pointer while it returns a 西格芬奇 type function pointer.
示例C程序来捕获3d捕鱼达人
大多数Linux用户使用组合键Ctr + C终止Linux中的进程。
Have you ever thought of what goes behind 这个. Well, whenever ctrl+c is pressed, a 3d捕鱼达人 SIGINT is sent to the process. The default action of 这个 3d捕鱼达人 is to terminate the process. But 这个 3d捕鱼达人 can also be handled. The following code demonstrates 这个 :
#include<stdio.h> #include<signal.h> #include<unistd.h> void sig_handler(int signo) { 如果(signo == SIGINT) 打印 ("received SIGINT\n"); } int main(void) { if (signal(SIGINT, sig_handler) == SIG_ERR) 打印 ("\ncan't catch SIGINT\n"); // A long long wait so that we can easily issue a 3d捕鱼达人 to 这个 process while(1) sleep(1); return 0; }
在上面的代码中,我们使用无限while循环模拟了一个长时间运行的过程。
A function sig_handler is used a s a 3d捕鱼达人 handler. This function is registered to the kernel 通过 passing it as the second argument of the system call ‘signal’在main()函数中。该函数的第一个参数‘signal’ is the 3d捕鱼达人 we 整型end the 3d捕鱼达人 handler to handle which is SIGINT in 这个 case.
附带说明一下,使用函数sleep(1)有一个原因。该函数已在while循环中使用,因此while循环会在一段时间后执行(在这种情况下为一秒钟)。这很重要,因为否则,无限期的while循环会疯狂运行,可能会消耗大量CPU,从而使计算机非常缓慢。
无论如何,返回,当进程运行时,我们尝试使用Ctrl + C终止进程:
$ ./sigfunc ^Creceived SIGINT ^Creceived SIGINT ^Creceived SIGINT ^Creceived SIGINT ^Creceived SIGINT ^Creceived SIGINT ^Creceived SIGINT
我们在上面的输出中看到,我们多次尝试了组合键ctrl + c,但是每次该过程’t terminate. This is because the 3d捕鱼达人 was handled in the code and 这个 was confirmed from the print we got 上 each line.
SIGKILL,SIGSTOP和用户定义的3d捕鱼达人
Apart from handling the standard 3d捕鱼达人s(like INT, TERM etc) that are available. We can also have user defined 3d捕鱼达人s that can be sent and handled. Following is the code handling a user defined 3d捕鱼达人 USR1 :
#include<stdio.h> #include<signal.h> #include<unistd.h> void sig_handler(int signo) { if (signo == SIGUSR1) 打印 ("received SIGUSR1\n"); else if (signo == SIGKILL) 打印 ("received SIGKILL\n"); else if (signo == SIGSTOP) 打印 ("received SIGSTOP\n"); } int main(void) { if (signal(SIGUSR1, sig_handler) == SIG_ERR) 打印 ("\ncan't catch SIGUSR1\n"); if (signal(SIGKILL, sig_handler) == SIG_ERR) 打印 ("\ncan't catch SIGKILL\n"); if (signal(SIGSTOP, sig_handler) == SIG_ERR) 打印 ("\ncan't catch SIGSTOP\n"); // A long long wait so that we can easily issue a 3d捕鱼达人 to 这个 process while(1) sleep(1); return 0; }
We see that in the above code, we have tried to handle a user defined 3d捕鱼达人 USR1. Also, as we know that two 3d捕鱼达人s KILL and STOP cannot be handled. So we have also tried to handle these two 3d捕鱼达人s so as to see how the ‘signal’在这种情况下,系统调用会响应。
当我们运行上面的代码时:
$ ./sigfunc can't catch SIGKILL can't catch SIGSTOP
所以上面的输出清楚地表明,只要系统调用‘signal’ tries to register handler for KILL and STOP 3d捕鱼达人s, the 3d捕鱼达人 function fails indicating that these two 3d捕鱼达人s cannot be caught.
Now we try to pass the 3d捕鱼达人 USR1 to 这个 process using the 杀死命令:
$ kill -USR1 2678
在运行上述程序的终端上,我们看到:
$ ./sigfunc can't catch SIGKILL can't catch SIGSTOP received SIGUSR1
So we see that the user defined 3d捕鱼达人 USR1 was received in the process and was handled properly.
如果您喜欢这篇文章,您可能还会喜欢..
![]() |
![]() |
![]() |
![]() |
谢谢!很棒的帖子!相当讲究和客观。恭喜! --