fork 和 signal:如何将信号从父进程发送到特定的子进程
Posted
技术标签:
【中文标题】fork 和 signal:如何将信号从父进程发送到特定的子进程【英文标题】:fork and signal: how to send signals from parent process to specific child process 【发布时间】:2017-01-09 13:43:50 【问题描述】:我需要fork
两个子进程。一个可以接收信号3,打印hello
并将信号4发送给另一个子进程;另一个可以接收信号4,打印world
并将信号3发送给第一个子进程。
启动时,父进程会在休眠 3 秒后向第一个子进程发送信号 3。
然后 3 秒后,父进程会发送SIGKILL
杀死他们两个。
我不知道如何向特定的子进程发送信号(我知道我们有一个函数kill
可以发送信号,但我不知道在这里使用它)。
这是我的代码:
#include <stdio.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
void func(int n)
printf("ping\n");
// how to send signal 4 to the second process?
void func2(int n)
printf("pong\n");
// how to send signal 3 to the first process?
int main()
pid_t pid;
int i;
for(i = 0; i < 2; i++)
pid = fork();
if(pid == 0)
if(i == 0)
signal(3, func);
else
signal(4, func2);
while(1);
else
if(i == 1)
sleep(3);
// how to send signal 3 to the first child process?
sleep(3);
// how to kill the two children?
return 0;
【问题讨论】:
在信号上下文中调用printf()
的未定义行为。
man7.org/linux/man-pages/man2/kill.2.html
@EOF 那我该怎么办?
@alk 但我仍然不知道如何向子进程发送信号。
kill()
系统调用是您所需要的。棘手的部分是您必须以某种方式告诉每个孩子其兄弟姐妹的 PID。也许父母通过在管道上写信息来告诉他们两个?或者,也许您使用进程组来发出信号。
【参考方案1】:
您可以使用 popen() 函数通过分叉并打开通往该进程的管道来打开该进程(而不是直接使用 fork())
父进程知道每个进程的 PID,因此可以轻松地将第二个子进程的 pid 传递给第一个子进程。
第一个孩子可以使用 pid 和 kill()` 函数将信号传递给第二个孩子。
所以,使用 popen() 启动第一个孩子。使用 fork() 启动第二个孩子,然后通过使用 popen() 创建的流将 pid 从第二个孩子传递给第一个孩子。
没有正确处理从调用 fork() 返回的 pid 值。
发布的代码假设对 fork() 的调用是成功的......这不是一个安全/有效的假设
代码还需要检查 pid 是否为 -1 并适当地处理该错误。
当子进程完成时,它不应该处于while()
循环中,而是应该退出,使用exit()
函数。
父进程不应该只是退出,因为这会使两个子进程成为僵尸进程。 (没有系统重启,僵尸很难摆脱。)
相反,父进程应该调用wait()
甚至更好的waitpid()
(并记住子进程需要实际退出,而不是坐在while()
循环中。
1) func()
和func2()
应该检查参数以确保它是正在处理的正确信号。
2) signal()
的手册页表明不应使用它。手册页建议使用:sigaction()
,
【讨论】:
【参考方案2】:当您 fork
时,您将获得新的 pid
。根据kill manpage,您使用pid
调用kill(pid_t pid, int sig);
【讨论】:
如果我在第一个sleep(3)
之后写kill(pid, 3)
,我认为它会发送给所有子进程。我需要的是发送到第一个子进程。
@Thomas:不;除非您对pid
使用零或负值,否则它将信号发送到一个进程。
好的。我得到了它。我还有一个问题:如何在进程之间共享 pid?因为我需要在func
中输入kill(4, secondProcessPid)
和在func2
中的kill(3, firstProcessPid)
。如何获得这两个pid?我必须使用共享内存之类的东西吗?
您对kill
的论点倒退了......在这种情况下,共享内存似乎有点过分了。当您fork()
时,子进程是父进程的副本。这包括全局变量和局部变量。以上是关于fork 和 signal:如何将信号从父进程发送到特定的子进程的主要内容,如果未能解决你的问题,请参考以下文章