我正在编写一个Linux守护进程来执行我的代码。我的代码调用了第三方库。如果我从父级执行我的代码,那么一切运行正常,但如果我直接从子代执行我的代码,则永远不会返回对第三方库的调用。如果我创建了第二个执行我的代码的可执行文件,并且让守护程序运行可执行文件,那么一切运行正常。
为什么我不能从子进程调用我的代码?
int main(void)
{
// Our process ID and Session ID
pid_t pid, sid;
fflush(stdout);
// Fork off the parent process
pid = fork();
if (pid < 0)
exit(EXIT_FAILURE);
// If we got a good PID, then we can exit the parent process.
if (pid > 0)
exit(EXIT_SUCCESS);
// Change the file mode mask
umask(0);
// Open any logs here
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
if (open("/dev/null",O_RDONLY) == -1)
exit(EXIT_FAILURE);
if (open("/dev/null",O_WRONLY) == -1)
exit(EXIT_FAILURE);
if (open("/dev/null",O_WRONLY) == -1)
exit(EXIT_FAILURE);
// Create a new SID for the child process
sid = setsid();
if (sid < 0)
exit(EXIT_FAILURE);
// Change the current working directory
if ((chdir("/")) < 0)
exit(EXIT_FAILURE);
// doesn't work
MyObject ob;
ob.start();
// works
//execlp("/home/root/NextGenAutoGuidance", "NextGenAutoGuidance", (char*)NULL);
while(1)
{
sleep(60);
}
exit(EXIT_SUCCESS);
}
我已经尝试将对象的对象声明作为全局和静态全局,我也尝试对我的对象进行新的/删除。
对第三方库的调用将返回的唯一方法是,如果我的对象是从父进程启动的。
如何创建守护进程以便我不必调用外部二进制文件才能正常运行?
我需要补充一点,我也试图不杀死父母,我也有同样的问题。
答案 0 :(得分:1)
经过几个小时的挖掘,我发现了问题的原因和解决方案。
原因:
我在MyObject类中有一个私有全局静态类对象,它启动了一个调用第三方库的线程。
因为类对象是全局的,所以它是在fork之前创建的,即使我在fork之后声明了MyObject。一旦创建了静态类对象,它就会启动一个调用第三方库的线程,并且在库函数中它会触发一个互斥锁。当你没有复制fork线程时,所以在fork之后父进程被杀死并且子进程创建了一个新的静态类对象,该对象启动了一个调用库函数并进入同一个互斥锁的新线程。因为父项没有释放互斥锁,因为它在离开库函数之前被杀死了,所以子进程一直在等待释放互斥锁。
解决方案:
不要在创建对象时创建线程,并等待子进程创建线程,直到fork之后。