use*_*904 6 c parallel-processing fork exec
就像标题所说的那样.我有一段代码如下:
pid_t = p;
p = fork();
if (p == 0) {
childfn();
} else if (p > 0) {
parentfn();
} else {
// error
}
Run Code Online (Sandbox Code Playgroud)
我想确保父或子在另一个之前执行(但不返回)各自的功能.
像sleep()这样的调用可能会起作用,但是不能通过任何标准来保证,并且只是利用操作系统调度程序的实现细节......这可能吗?vfork会工作吗?
编辑:两个函数都找到了一个system()调用,其中一个函数在另一个函数启动之前不会返回.所以要重新迭代:我需要确保父或子只调用它们各自的函数(但不返回,因为它们不会,这是下面提供的所有基于互斥锁的解决方案提供的).有任何想法吗?抱歉缺乏清晰度.
edit2:有一个进程调用sched_yield和sleep,我似乎得到了非常可靠的结果.vfork确实提供了我正在寻找的语义,但是对于我在子进程中可以做的事情有很多限制(我几乎只能调用exec).所以,我发现了一些足够好的解决方案,但没有真正的解决方案.vfork可能是我所寻找的最接近的东西,但下面提出的所有解决方案都会或多或少地起作用.
互斥锁应该能够解决这个问题.在调用fork之前锁定互斥锁并使第一个函数正常执行,而第二个函数尝试声明互斥锁.第一个应该在完成时解锁互斥锁,第二个将等到它是空闲的.
编辑:互斥锁必须位于两个进程的共享内存段中
// Get a page of shared memory
int pagesize = getpagesize();
void *mem = mmap(NULL, pagesize, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
if(!mem)
{
perror("mmap");
return 1;
}
// Put the semaphore at the start of the shared page. The rest of the page
// is unused.
sem_t *sem = mem;
sem_init(sem, 1, 1);
pid_t p = fork();
if (p == 0) {
sem_wait(sem);
childfn();
sem_post(sem);
} else if (p > 0) {
sem_wait(sem);
parentfn();
sem_post(sem);
int status;
wait(&status);
sem_destroy(sem);
} else {
// error
}
// Clean up
munmap(mem, pagesize);
Run Code Online (Sandbox Code Playgroud)
您还可以在共享内存区域中使用互斥锁,但是您需要确保使用非默认属性创建,并将进程共享属性称为共享(通过pthread_mutexattr_setpshared(&mutex, PTHREAD_PROCESS_SHARED))以使其工作.
这确保了在任何给定时间只能执行一个childfn或parentfn将执行,但它们可以按任何顺序运行.如果你需要先运行一个特定的运行,请以1为1而不是0来启动信号量,并且需要先运行的函数不要等待信号量(但在完成时仍然会发送到它).您也可以使用具有不同语义的条件变量.