子进程和父进程执行是并行的,首先启动取决于操作系统调度。但是,在父母之前总是可以做些什么呢?
这是我的问题的伪代码,
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应该按顺序。
答案 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
此外,如果您能指定实际问题,我可以适当地建议您。
答案 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
}