gpt4 book ai didi

c++ - fork() 没有按预期工作

转载 作者:太空宇宙 更新时间:2023-11-04 09:34:08 24 4
gpt4 key购买 nike

我正在尝试创建一个产生两个进程的程序——第一个进程监视第二个进程,并在它被终止时重新启动它。 (想法是杀死第二个进程的唯一方法是先杀死第一个进程。)下面我的代码无法实现我的目标。

#include <cstdio>
#include <unistd.h>
#include <thread>
#include <chrono>
#include <signal.h>
#include <cerrno>

void makeSiblings();

void run_ping() {

while (true) {

std::this_thread::sleep_for(std::chrono::seconds(2));
puts("Ping.");
}
}

void run_monitor(pid_t sibling) {

while (kill(sibling, 0) != -1 and errno != ESRCH) {

printf("%d still exists.\n", sibling);
std::this_thread::sleep_for(std::chrono::seconds(1));
}

makeSiblings();
}

void makeSiblings() {

pid_t pid1, pid2;

if ((pid1 = fork()) == -1) {

perror("fork");
exit(EXIT_FAILURE);
}

if (pid1 == 0) {

setsid();
run_ping();
}

if ((pid2 = fork()) == -1) {

perror("fork");
exit(EXIT_FAILURE);
}

if (pid2 == 0) {

setsid();
run_monitor(pid1);
}
}

int main() {

makeSiblings();
}

运行此代码时,它会输出 Ping。,例如7812 仍然存在。 分别每两秒和一秒——正如预期的那样。然而,当我从另一个终端 kill 7812 时,“Ping”进程激增到一个荒谬的程度——我似乎在用 fork 轰炸自己,这只是通过发送垃圾邮件 killall 我能够恢复。

我似乎未能理解有关 fork()setsid() 的一些微妙之处。我将不胜感激一两个指点。

最佳答案

是的,你是 fork bombimg...你的函数调用 fork() 两次,然后两个 child 最终将递归调用 makeSiblings()

当调用 run_ping() 的第一个子进程完成时,它实际上并未完成,但会调用 run_monitor()。然后它将调用 makeSiblings() 并重复直到它爆炸!

解决方案是在 run_ping() 之后添加一个 exit() 调用:

if (pid1 == 0) {
setsid();
run_ping();
exit(EXIT_SUCCESS); // <------ here!
}

另请注意,您正在 makeSiblings()run_monitor() 之间进行尾递归,这可能不是一个好主意,因为您的堆栈可能会溢出。

我会这样写:

void run_monitor(pid_t sibling) {
while (kill(sibling, 0) != -1 and errno != ESRCH) {
//...
}
}

void makeSiblings() {
pid_t pid2 = fork(); //error code ommited

setsid();
if (pid2 != 0)
return;

//this is now the monitor process
while (true) {
pid_t pid1 = fork(); //error code ommited
if (pid1 == 0) {
setsid();
run_ping();
exit(EXIT_SUCCESS);
}
run_monitor(pid1);
}
}

但是现在,您只需使用 wait() 而不是 kill(pid, 0),因为 ping() 进程是一个监视器的 child ,因为它应该是。

关于c++ - fork() 没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28495381/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com