C-使用fork(),如何使子过程始终首先运行



孩子和父进程的执行是平行的,首先启动取决于OS调度。但是,如何始终在父母面前开始孩子怎么办?

这是我问题的伪代码,

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都应序列。

我真的不知道为什么人们一直在告诉不依靠这种行为,它实际上在跟踪程序中使用了很多(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
}

您可以在pthread(POSIX线程)的情况下实现此操作,但在过程中不能实现。看,过程计划始终掌握在内核手中,您无法明确操纵。在并行处理系统中,所有过程(无论是子进程,父程进程还是其他僵尸过程)都是并行执行的,您无法更改。sleep()方法可以起作用,但是遵循的方法非常差。

1。通过使用信号处理。

当您 fork()一个新的子过程时,就在然后您 sleep()pause()父进程。在父母过程中处于等待位置的情况下,将执行子进程。然后,子进程发送自定义信号,该信号将通过父进程进行手写以继续执行。(这也很忙,因为您需要在程序中处理信号)。

2。通过使用系统调用。

通过使用系统调用,您可以处理过程状态(准备,暂停,终止等)。有某些隐式使用系统信号处理来更改过程状态/优先级的壳命令。如果您知道ProcessID(PID),则可以做:

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

,如果要进行C编程,您可以做:

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

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

有关更多参考,您可以打开此页面。

此外,如果您可以指定要实施此操作的实际问题,我可以适当建议您。

使用具有初始值0的二进制信号。孩子开始后,它可以发出信号量(即使其1)发出信号。然后,父母的等待将结束,它将进步。

在Linux中,如果要先运行子进程,则需要使用 kernel.sched_child_runs_first sysctl参数

不能保证在另一个过程之前安排一个过程。即使您将父母放在sleep()上,如果其他进程在叉子之后立即抢占父母,则可能会碰到孩子的执行。孩子和父母可以在两个CPU上真正同行运行。

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

简而言之:不要编写代码以依靠不能保证的行为。

线程提供了更多的机制来同步并行代码执行。您可能会看看Pthread。请注意,线程 - 与过程不同 - 共享可能引发其他问题之类的资源。

只需放置等待(0);在父母内部。因此,父母会等到孩子完成。

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

相关内容

  • 没有找到相关文章