[英]C/C++ linux fork() and exec()
我正在使用fork()创建子进程。 从子进程中,我使用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函数将是打开文件,写入日志和关闭文件。 (刷新)ShellScript将启动新的进程c / c ++。
我长期运行我的程序,上面的代码多次被调用。 有时(很少)会发生问题,尽管成功创建了子进程(我已经仔细检查),但新进程无法成功启动。 当此问题发生时,尽管成功创建了子进程,但仍然无法打印“子进程”日志,这是一件非常令人误解的事情。
在正常情况下(不会发生错误),“子进程”和“父进程”日志的打印次数相同。
在异常情况下,尽管子进程始终成功创建,但它们并不相同。在这种情况下,不会打印“启动进程失败”和“无法创建子进程”日志。 请帮我咨询。
请记住, stdio(3)已缓冲。 总是调用fflush(NULL);
(见fflush(3)之前对更多) fork
。 在每个printf(3)格式字符串的末尾添加一个\\n
(换行符)(否则,在fflush(NULL);
加上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
应
} else {
perror("Can't create child process");
fflush(NULL);
}
您可能想使用strace(1) (特别是strace -f yourprog
...)来了解所涉及的syscall (请参阅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) 。
分叉进程的数量有限制,请参阅带有RLIMIT_NPROC
和内置bash ulimit
setrlimit(2) 。
另请阅读高级Linux编程 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.