使用fork(),我如何才能首先运行子进程?

时间:2015-05-16 13:26:36

标签: c linux process fork vfork

子进程和父进程执行是并行的,首先启动取决于操作系统调度。但是,在父母之前总是可以做些什么呢?

这是我的问题的伪代码,

int start_test()
{
   pid_t pid;
   pid = fork();
   if(pid == 0) {
      execv("XXX", XXX);
   } else if(pid > 0) {
     pid = fork();
    if(pid == 0) {
       execv("XXX", XXX);
    } else {
       // Do something
    }
   }
  return 0;
}
int main()
{
   start_test();
   return 0;
}

我想首先执行execv,然后再次创建新进程。每个execv应该按顺序。

6 个答案:

答案 0 :(得分:6)

我真的不知道人们为什么一直告诉他们不要依赖这种行为,它实际上在追踪程序(strace,ldtrace,......)中使用了很多。

首先,分叉您的进程并获取子进程pid,停止该进程并在父进程中恢复:

pid_t pid = fork();
if (pid == -1)
    abort();
else if (pid == 0) {
    raise(SIGSTOP); // stop the child
} else {
    waitpid(pid, NULL, WUNTRACED); // wait until the child is stopped
    kill(pid, SIGCONT); // resume the child
}

答案 1 :(得分:1)

您可以在pthread(POSIX线程)的情况下实现此功能,但在进程的情况下则不能。 请注意,进程调度始终掌握在内核中,并且您无法明确地进行操作。在并行处理系统中,所有进程(无论是子进程,父进程还是其他僵尸进程)都是并行执行的,您无法更改。 sleep()方法可以起作用,但这种方法很难被遵循。

<强> 1。通过利用信号处理。

当您fork()新的子流程时,您只需sleep()pause()父流程。子进程将在父进程处于等待位置时执行。然后子进程发送自定义信号,该信号将被父进程处理以继续执行。 (这也很忙,因为你需要在程序中处理信号)。

<强> 2。通过使用系统调用。

通过使用系统调用,您可以处理进程状态(就绪,挂起,终止等)。某些shell命令隐式使用系统信号处理来更改进程状态/优先级。如果您知道processID(pid),那么您可以这样做:

kill -SIGSTOP [pid]
kill -SIGCONT [pid]

如果是c编程,你可以这样做:

system("kill -SIGSTOP [pid]"); //pause

system("kill -SIGCONT [pid]"); //resume

For more reference you can open this page.

此外,如果您能指定实际问题,我可以适当地建议您。

答案 2 :(得分:0)

无法保证在另一个进程之前安排一个进程。即使你将父项放到sleep(),如果其他进程在fork之后立即抢占了父进程,那么很可能先发生子进程。孩子和父母可以在两个CPU上并行运行。

实际上,这样做是没有价值的。如果两个进程之间需要某种同步,请使用管道/信号等显式机制

简而言之:不要编写代码来依赖无法保证的行为。

线程提供了更多同步并行代码执行的机制。你可以看一下pthread。请注意,线程 - 与进程不同 - 共享内存等资源,这可能会带来其他问题。

答案 3 :(得分:0)

使用初始值为0的二进制信号量。在fork之后,parent应该等待信号量。在孩子开始之后,它可以发信号通知信号量(即,使其成为1)。然后,父母的等待将结束,它将会进展。

答案 4 :(得分:0)

在linux中,如果您希望首先运行子进程,则需要使用kernel.sched_child_runs_first sysctl参数

答案 5 :(得分:0)

只需等待(0);在父母内部。 所以父母会等到孩子完成。

if(child){
 //do whatever
}
if(parent{
wait(0);
// so whatever
}