是否可以fork/exec并保证一个在另一个之前启动?

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可能是我所寻找的最接近的东西,但下面提出的所有解决方案都会或多或少地起作用.

Bob*_*hiv 5

互斥锁应该能够解决这个问题.在调用fork之前锁定互斥锁并使第一个函数正常执行,而第二个函数尝试声明互斥锁.第一个应该在完成时解锁互斥锁,第二个将等到它是空闲的.

编辑:互斥锁必须位于两个进程的共享内存段中


Ada*_*eld 5

这个问题通常可以通过互斥锁信号量来解决.例如:

// 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))以使其工作.

这确保了在任何给定时间只能执行一个childfnparentfn将执行,但它们可以按任何顺序运行.如果你需要先运行一个特定的运行,请以1为1而不是0来启动信号量,并且需要先运行的函数不要等待信号量(但在完成时仍然会发送到它).您也可以使用具有不同语义的条件变量.