守护进程 child 无法执行库
Daemon child can't execute library
我正在编写一个 Linux 守护进程来执行我的代码。我的代码调用第三方库。如果我从 parent 执行我的代码,那么一切 运行 都很好,但是如果我直接从 child 执行我的代码,那么对第三方库的调用永远不会 returns .如果我创建第二个执行我的代码的可执行文件并且我有守护程序 运行 可执行文件那么一切 运行 都很好。
为什么我不能从 child 进程调用我的代码?
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);
}
我试过将我的 object 的 object 声明作为全局和静态全局,我也尝试过对我的 object 做一个 new/delete。
如果我的 object 从 parent 进程启动,那么调用第三方库 return 的唯一方法是。
如何创建守护程序,以便我不必正确调用外部二进制文件 运行?
编辑
我需要补充一点,我也尝试过不杀死 parent,但我遇到了同样的问题。
经过几个小时的挖掘,我找到了问题的原因和解决方案。
原因:
我在 MyObject class 中有一个私有全局静态 class 对象,它启动了一个调用第三方库的线程。
因为 class 对象是全局对象,它是在分叉之前创建的,即使我在分叉之后声明了 MyObject。一旦创建了静态 class 对象,它就会启动一个调用第三方库的线程,并且在库函数中它会遇到互斥锁。当你 fork 线程没有被复制时,所以在 fork 之后父进程被杀死并且子进程创建了一个新的静态 class 对象,该对象启动了一个新线程,该线程调用库函数并到达同一个互斥体。因为互斥体在离开库函数前被kill掉,父进程没有释放,子进程卡在等待释放互斥体。
解决方案:
不要在创建对象时创建线程并等待子对象创建线程直到 fork 之后。
我正在编写一个 Linux 守护进程来执行我的代码。我的代码调用第三方库。如果我从 parent 执行我的代码,那么一切 运行 都很好,但是如果我直接从 child 执行我的代码,那么对第三方库的调用永远不会 returns .如果我创建第二个执行我的代码的可执行文件并且我有守护程序 运行 可执行文件那么一切 运行 都很好。
为什么我不能从 child 进程调用我的代码?
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);
}
我试过将我的 object 的 object 声明作为全局和静态全局,我也尝试过对我的 object 做一个 new/delete。
如果我的 object 从 parent 进程启动,那么调用第三方库 return 的唯一方法是。
如何创建守护程序,以便我不必正确调用外部二进制文件 运行?
编辑
我需要补充一点,我也尝试过不杀死 parent,但我遇到了同样的问题。
经过几个小时的挖掘,我找到了问题的原因和解决方案。
原因:
我在 MyObject class 中有一个私有全局静态 class 对象,它启动了一个调用第三方库的线程。
因为 class 对象是全局对象,它是在分叉之前创建的,即使我在分叉之后声明了 MyObject。一旦创建了静态 class 对象,它就会启动一个调用第三方库的线程,并且在库函数中它会遇到互斥锁。当你 fork 线程没有被复制时,所以在 fork 之后父进程被杀死并且子进程创建了一个新的静态 class 对象,该对象启动了一个新线程,该线程调用库函数并到达同一个互斥体。因为互斥体在离开库函数前被kill掉,父进程没有释放,子进程卡在等待释放互斥体。
解决方案:
不要在创建对象时创建线程并等待子对象创建线程直到 fork 之后。