单进程场景
在单进程的情况下,ctrl+c和kill -2是一模一样的,都是向指定的进程发送SIGINT信号.
如果进程中注册了捕捉SIGINT信号的处理函数,那么这个信号会被进程处理,例如:
void processB() {// Set signal handler for SIGINT in process Bsignal(SIGINT, sigint_handler);printf("I am B process\n");while (1) {printf("B: Working...\n");sleep(1);}
}
如果没有注册这个信号捕捉,当信号触发时,操作系统将会终止这个进程的运行.相关资源也会由系统回收.
非单进程场景
试想一种场景,A进程作为父进程启动之后拉起子进程B。这个时候对A进程发送kill -2或者ctrl + c,这两种情况下,产生的结果是否一致?
我们可以写一个简单的测试程序来验证我们的想法:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>void sigint_handler(int signum) {printf("Capture Ctrl+C signal:%d\n", signum);
// exit(EXIT_SUCCESS);
}void processB() {// Set signal handler for SIGINT in process Bsignal(SIGINT, sigint_handler);printf("I am B process\n");while (1) {printf("B: Working...\n");sleep(1);}
}int main() {// Set signal handler for SIGINT in process Asignal(SIGINT, sigint_handler);pid_t child_pid = fork();if (child_pid == -1) {perror("Fork failed");exit(EXIT_FAILURE);}if (child_pid > 0) {// This is the parent processprintf("I am a process\n");while (1) {printf("Parent: Working...\n");sleep(1);}} else {// This is the child processprocessB();}return 0;
}
使用指令:gcc -o cotrol_and_C_test cotrol_and_C_test.c
来编译你的测试程序。
测试发现:
1,对当前进程A执行ctrl+c时,A/B进程同时退出
2,对当前进程B执行kill -2时,只有A进程退出,B进程依旧在运行
现象其实很好解释:
1,对当前进程A执行ctrl+c时,A/B进程同时退出
--> 当A进程启动B进程之后,AB进程同属与同一个进程组,你可以使用ps -e -o pid,pgid,cmd 指令查看:
38057 0 [kworker/3:0-cgr]38069 0 [kworker/2:2-cgr]38080 0 [kworker/0:1-cgr]38149 38149 ./cotrol_and_C_test38150 38149 ./cotrol_and_C_test38151 38151 ps -e -o pid,pgid,cm
当发生ctrl+c时,这个信号是同时发送给了这个进程组中所有的进程,这其中也包括了进程B
2,对当前进程B执行kill -2时,只有A进程退出,B进程依旧在运行
--> 这种情况下,因为执行的是kill -2 $pid, 这个时候SIGINT信号只发送给了$pid进程,并不会发送给进程组的其他成员,所以他们并不能收到这个信号。
扩展
http://zyearn.com/blog/2015/03/22/what-happens-when-you-kill-a-process/
这篇文章介绍的不错。