简体   繁体   English

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

[英]C/C++ linux fork() and exec()

I'm use fork() to create child process. 我正在使用fork()创建子进程。 From child process I am use exec() to launch new process. 从子进程中,我使用exec()启动新进程。 My code as below: 我的代码如下:

   ......
   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");
   }
   ......

Note: WriteLog function will be open file, write log, and close file. 注意:WriteLog函数将是打开文件,写入日志和关闭文件。 (It is flushed) ShellScript will launch new process c/c++. (刷新)ShellScript将启动新的进程c / c ++。

I run my program for long run and the code above is called many times. 我长期运行我的程序,上面的代码多次被调用。 And sometime (rarely) there are problem happen that the new process can't launch successful although the child process is created successfully (I have checked carefully). 有时(很少)会发生问题,尽管成功创建了子进程(我已经仔细检查),但新进程无法成功启动。 And one thing is extremely misunderstand when this problem happen that the "Child process" log can't printed although the child process is created successful. 当此问题发生时,尽管成功创建了子进程,但仍然无法打印“子进程”日志,这是一件非常令人误解的事情。

In normal case (there are not error happen) the number of times print the "Child process" and "Parent process" log are the same. 在正常情况下(不会发生错误),“子进程”和“父进程”日志的打印次数相同。

In abnormal case, they are not the same although the child process always create successfully.The "Launch process fail" and "Can't create child process" log aren't printed in this case. 在异常情况下,尽管子进程始终成功创建,但它们并不相同。在这种情况下,不会打印“启动进程失败”和“无法创建子进程”日志。 Please help me for consult. 请帮我咨询。

Remember that stdio(3) is buffered. 请记住, stdio(3)已缓冲。 Always call fflush(NULL); 总是调用fflush(NULL); (see fflush(3) for more) before fork . (见fflush(3)之前对更多) fork Add a \\n (newline) at end of every printf(3) format string (or else, follow them by fflush(NULL); ...). 在每个printf(3)格式字符串的末尾添加一个\\n (换行符)(否则,在fflush(NULL);加上fflush(NULL); ...)。

The function execl(3) (perhaps you want execlp ?) can fail (so sets errno on failure). 函数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");
}

On error, fork(2) fails by returning -1 and sets errno(3) (see also perror(3) and strerror(3) ). 出错时, fork(2)失败,返回-1并设置errno(3) (另请参阅perror(3)strerror(3) )。 So your last else should be 所以,你的最后else

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

You might want to use strace(1) (notably as strace -f yourprog ...) to understand the involved syscalls (see syscalls(2) ...) 您可能想使用strace(1) (特别是strace -f yourprog ...)来了解所涉及的syscall (请参阅syscalls(2) ...)

Your WriteLog should probably use strerror (on the errno value saved at beginning of WriteLog ....). 您的WriteLog可能应该使用strerror (在WriteLog .... 开始时保存的errno值上)。 I suggest something like 我建议类似

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

See syslog(3) . 参见syslog(3)

There are limits on the number of fork-ed processes, see setrlimit(2) with RLIMIT_NPROC and the bash ulimit builtin. 分叉进程的数量有限制,请参阅带有RLIMIT_NPROC和内置bash ulimit setrlimit(2)

Read also Advanced Linux Programming . 另请阅读高级Linux编程

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM