代码:(感谢lwx提供)
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
int flag;
void child_process(int sig) {
if (sig == 16) {
printf("Process 1 received signal %d.\n", sig);
flag = 0;
}
else if (sig == 17)
{
printf("Process 2 received signal %d.\n", sig);
flag = 0;
}
}
void parent_process(int sig) {
printf("Parent received signal SIGQUIT.\n");
}
int main() {
pid_t sub_pro1, sub_pro2;
// 创建两个子进程
sub_pro1 = fork();
if (sub_pro1 < 0) {
perror("fork");
exit(1);
}
else if (sub_pro1 == 0) {
// 子进程1
printf("task1 start!\n");
signal(SIGQUIT, SIG_IGN);
flag = 1;
while (flag)
{
signal(16, child_process); // 捕获信号16
if (flag == 0) printf("child process 1 is killed by parent!\n");
}
exit(0);
}
else {
sub_pro2 = fork();
if (sub_pro2 < 0) {
perror("fork");
exit(1);
}
else if (sub_pro2 == 0) {
// 子进程2
printf("task2 start!\n");
signal(SIGQUIT, SIG_IGN);
flag = 1;
while (flag)
{
signal(17, child_process); // 捕获信号17
if (flag == 0) printf("child process 2 is killed by parent!\n");
}
exit(0);
}
else {
// 父进程
signal(SIGQUIT, parent_process); // 捕获SIGQUIT信号
// 等待SIGQUIT信号
pause();
// 收到SIGQUIT信号后向两个子进程发送信号
kill(sub_pro1, 16);
// 等待子进程1结束
wait(0);
kill(sub_pro2, 17);
// 等待子进程2结束
wait(0);
// 显示结束信息并退出
printf("parent process is killed.\n");
exit(0);
}
}
}
涉及到的函数:
signal():
signal()
函数是用于在程序中设置信号处理函数的函数。它的原型如下:
void (*signal(int signum, void (*handler)(int)))(int);
//gpt写的,看不懂,我一般写signal(SIGQUIT, handler);
- 第一个参数
signum
指定了要捕获的信号的编号,比如SIGINT
、SIGSEGV
等。 - 第二个参数
handler
是一个函数指针,指向一个处理该信号的函数。可以是预定义的信号处理函数,也可以是自定义的处理函数。 signal()
函数返回之前与该信号相关联的信号处理函数的地址。
通过signal()
函数,程序可以在接收到指定信号时执行特定的操作或函数,比如捕捉Ctrl+C
中断信号,进行资源释放等操作。
kill():
kill()
函数的命名可能是源自于其最常用的功能,即向进程发送终止信号(SIGKILL
),从而"杀死"该进程。虽然kill()
函数也可以发送其他类型的信号,但因为终止信号是其最常用的功能,因此这个函数被命名为kill()
。
kill()
函数的主要作用是向指定进程发送信号,其中最常见的是SIGKILL
信号,它可以用来强制终止一个进程。实际上,在Linux环境下,用来终止进程的确切命令是SIGTERM
或SIGINT
,但SIGKILL
是一种特殊的信号,可以立即终止进程,即使进程没有机会捕获或忽略信号也能生效。所以通常情况下,我们用kill()
函数发送SIGKILL
信号来杀死进程。
pause()、sleep(1)、和wait(0)的区别:
-
pause()
: 这个函数会使当前进程挂起,直到接收到一个信号为止。通常用于等待信号的到来,一旦收到信号,进程就会继续执行。 -
sleep(1)
: 这个函数会使当前进程挂起指定的秒数。例如,sleep(1)
会让进程休眠1秒钟,然后再继续执行。 -
wait(0)
: 这个函数通常在父进程中调用,用于等待子进程的结束。参数0
表示等待任意子进程结束,如果有子进程已经结束,它会立即返回。如果没有子进程结束,它会一直阻塞直到有子进程结束为止。wait()
函数默认等待任何一个子进程结束,类似于wait(-1)
的行为。因此,使用wait()
函数和wait(0)
是等价的。在某些上下文中,人们可能更喜欢使用wait(0)
来明确表达其意图,即等待任何一个子进程结束,而不是传递一个未指定的PID,要指定可以用waitpid(pid)