【发布时间】:2021-08-22 08:46:35
【问题描述】:
背景:
我的程序 test.c 正在创建一个守护进程。
来自 test.c 的代码 sn-p 创建一个守护进程。
sigset_t set;
pid_t pid;
if ((pid = fork()) < 0)
{
printf("Did not create the daemon process\n");
exit(1);
}
else if (pid != 0)
{
exit(0);
}
setsid();
chdir("/");
closefiles();
...
我使用 rc 脚本来启动我的程序 test.c。
问题:
在极少数情况下,我看到脚本挂起,并且 test.c 守护进程挂在 fork() 系统调用中。
在 gdb 中看到的进程的回溯。
(gdb) bt
#0 0x00007f6743dd5859 in __unregister_atfork () from /lib64/libc.so.6
#1 0x00007f6744f215f3 in __do_global_dtors_aux () from <an internal library>
#2 0x00007ffd358e29b0 in ?? ()
#3 0x00007f674566786a in _dl_fini () from /lib64/ld-linux-x86-64.so.2
Backtrace stopped: frame did not save the PC
我认为这可能是由于比赛条件。我可以理解父进程甚至在子进程中的 fork() 系统调用完成执行之前就退出了,这导致了某种死锁。这似乎发生在一个非常小的时间窗口内,因为在 exit(0) 之前添加 printf() 语句会导致脚本和守护进程成功执行。
此代码有效!
sigset_t set;
pid_t pid;
if ((pid = fork()) < 0)
{
printf("Did not create the daemon process\n");
exit(1);
}
else if (pid != 0)
{
printf("Parent process about to exit\n");
exit(0);
}
printf("Started child process\n");
setsid();
chdir("/");
...
我想了解的内容:
- 如何调试此问题以了解 exit() 导致 fork() 挂起的原因。
- 解决此问题的理想方法是什么?我在想我可以在成功执行 fork() 后向父级发出信号,只有在它收到父级应该退出的信号之后。
【问题讨论】:
-
您或您的编辑内部图书馆是使用
pthread_atforkin an unsafe way,但没有告诉我们吗?
标签: c linux process fork daemon