C / C ++ linux fork()和exec()

我使用fork()来创buildsubprocess。 从subprocess我用exec()来启动新进程。 我的代码如下:

...... pid = fork(); if (pid > 0) { WriteLog("Parent Process"); //Do something } else if (pid == 0) { WriteLog("Child process"); int return = execl(ShellScript); if ( return == -1 ) WriteLog("Launch process fail"); } else { WriteLog("Can't create child process"); } ...... 

注意:WriteLog函数将打开文件,写入日志和closures文件。 (被刷新)ShellScript将会启动新的进程c / c ++。

我长期运行我的程序,上面的代码被多次调用。 有时(很less)有问题发生,虽然subprocess被成功创build(我仔细检查过),新进程无法启动成功。 有一件事是极端的误解,当这个问题发生时,虽然subprocess创build成功,但“subprocess”日志不能打印。

在正常情况下(没有错误发生),打印“subprocess”和“父进程”日志的次数是相同的。

在不正常的情况下,虽然subprocess始终创build成功,但它们并不相同。在这种情况下,“启动进程失败”和“无法创buildsubprocess”日志不会被打印。 请帮我咨询一下。

请记住, stdio(3)被缓冲。 总是调用fflush(NULL); (更多见fflush(3) )。 在每个printf(3)格式字符串的末尾添加一个\n (换行符)(否则,按照fflush(NULL); …)。

函数execl(3) (也许你想execlp ?)可能会失败(所以在失败时设置errno )。

 } else if (pid == 0) { printf("Child process\n"); fflush(NULL); execl("/bin/foo", "foo", "arg1", NULL); // if we are here execl has failed perror("Launch process fail"); } 

错误时, fork(2)返回-1并设置errno(3) (另请参见perror(3)和strerror(3) )。 所以你的最后一个应该是

 } else { perror("Can't create child process"); fflush(NULL); } 

您可能想使用strace(1) (特别是strace -f yourprog …)来理解所涉及的系统调用 (请参阅syscalls(2) …)

您的WriteLog应该可能使用strerror (在WriteLog 开始时保存的errno值….)。 我建议像

  void WriteLog(const char* msg) { int e = errno; if (e) syslog (LOG_ERR, "%s [%s]", msg, strerrno(e)); else syslog (LOG_ERR, "%s", msg); } 

参见syslog(3) 。

fork-ed进程的数量是有限制的,参见使用RLIMIT_NPROC和bash ulimit内建的setrlimit(2) 。

另请阅读高级Linux编程 。