C / C ++ Linux的fork()和EXEC() [英] C/C++ linux fork() and exec()

查看:1225
本文介绍了C / C ++ Linux的fork()和EXEC()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用fork()创建子进程。从子进程我使用EXEC()来启动新的进程。我的code如下:

  ......
   PID =叉();
   如果(PID大于0){
       WRITELOG(父进程);
       //做一点事
   }如果别人(PID == 0){
       WRITELOG(子进程);
       int返回= EXECL(shellscript里);
       如果(返回== -1)
          WRITELOG(发射过程失败);
   }其他{
       WRITELOG(无法创建子进程);
   }
   ......

请注意:WRITELOG功能将被打开的文件,写日志,并关闭文件。 (它是刷新)
      shellscript里将推出新的进程的C / C ++。

我运行我的程序为长远及以上code被称为多次。和某个(很少),有问题发生,虽然成功创建子进程(我已经仔细地检查)新的进程无法启动成功。还有一件事是非常误解时,这个问题发生,虽然创建成功的子进程的子进程日志无法打印。

在正常情况下(有没有错误发生)的次数打印子进程和父进程日志是一样的。

在不正常的情况下,他们是不一样的,虽然子进程始终创建successfully.The启动过程失败和无法创建子进程的日志在这种情况下不打印。
请帮我咨询一下。


解决方案

记住的 STDIO(3)是缓冲。随时拨打 fflush(NULL); (见的 叉之前更fflush(3)。在每一个的 \\ n (新行) 相对=nofollow>的printf(3)格式字符串(否则,跟随他们通过 fflush(NULL); ...)

功能 EXECL(3)(也许你想 execlp ?)可能会失败(所以套错误号失败)。

 }否则如果(PID == 0){
   的printf(子进程\\ n);
   fflush(NULL);
   EXECL(/斌/富,富,ARG1,NULL);
   //如果我们在这里EXECL失败
   PERROR(发射过程失败);
}

在错误,叉(2)通过返回失败-1,并设置错误号(3)(也<见HREF =htt​​p://man7.org/linux/man-pages/man3/perror.3.html相对=nofollow> PERROR(3)和的字符串错误(3))。所以,你的最后一个其他

 }其他{
    PERROR(无法创建子进程);
    fflush(NULL);
}

您可能需要使用 strace的(1)(特别是作为 strace的-f yourprog ...)了解所涉及的系统调用(见系统调用(2) ...)

WRITELOG 应该使用字符串错误(关于错误号保存在开始 WRITELOG > ....)。我建议像

 无效WRITELOG(为const char *味精){
   INT E =错误号;
   如果(E)
     系统日志(LOG_ERR,%S [%S],味精,strerrno(e)条);
   其他
     系统日志(LOG_ERR,%S,味精);
 }

请参阅的syslog(3)

有上叉编辑流程,请参见了setrlimit的数量限制(2)用 RLIMIT_NPROC 和bash的的ulimit 内置

阅读也高级Linux编程

I'm use fork() to create child process. From child process I am use exec() to launch new process. 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. (It is flushed) ShellScript will launch new process 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. Always call fflush(NULL); (see fflush(3) for more) before fork. Add a \n (newline) at end of every printf(3) format string (or else, follow them by fflush(NULL); ...).

The function execl(3) (perhaps you want execlp?) can fail (so sets errno on failure).

} 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)). So your last else should be

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

Your WriteLog should probably use strerror (on the errno value saved at beginning of WriteLog ....). 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).

There are limits on the number of fork-ed processes, see setrlimit(2) with RLIMIT_NPROC and the bash ulimit builtin.

Read also Advanced Linux Programming.

这篇关于C / C ++ Linux的fork()和EXEC()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆