我有一个应用程序,它通过fork()创建许多进程。在某些时候,我想暂停所有这些并等到所有人完成早期任务。然后马上启动它们。
for (int i = 0; i < N; i++)
{
if(fork() == 0)
{
//some operations here
<----- wait here for all N forked processes
//some operations I want all processes start at similiar time
我不想让任何孩子退出。
答案 0 :(得分:2)
这似乎是为信号量量身定制的。具体来说,这很容易用“System V信号量”实现。请参阅semget(2)
和semop(2)
。
这个想法是你在父级中获得一个信号量,将其值初始化为N
,然后让每个孩子“准备好”将值递减1.所有孩子等待结果变为0。瞧。
这是一个示例程序
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#define N 5
int main(int ac, char **av)
{
int i, n, sem_id;
sem_id = semget(IPC_PRIVATE, 1, 0777);
struct sembuf buf;
buf.sem_num = 0;
buf.sem_flg = 0;
// Initialize semaphore value to N
buf.sem_op = N;
n = semop(sem_id, &buf, 1);
// All children will do the same thing:
// decrement semaphore value by 1
// wait for semaphore value == 0
for (i = 0; i < N; ++i) {
if (fork() == 0) {
printf("Child %d (%d) started\n", i, getpid());
sleep(i + 1); // Sleep awhile.
buf.sem_op = -1;
n = semop(sem_id, &buf, 1);
buf.sem_op = 0;
n = semop(sem_id, &buf, 1);
printf("Child %d (%d) done\n", i, getpid());
return 0;
}
}
return 0;
}
答案 1 :(得分:0)
有许多方法可以与流程进行通信,它被称为IPC(进程间通信)。这取决于您需要发送什么样的信息,大小等等。过程信号也是控制过程的一种方式。
以下是一些可以帮助您入门的资源:
答案 2 :(得分:0)
您可以使用的是像信号量这样的同步构造。 在代码处,你想要停止所有的孩子,让他们在队列中等待(在信号量上调用等号为0作为初始值)信号量,因此它们都会阻塞。
在父母身上,你可以发出信号量信号,从而启动信号量。
答案 3 :(得分:0)
我强烈推荐Message Passing Interface (MPI),因为它有MPI_Barrier
你可以用来实现你想要的,几乎没有逻辑你必须自己编码。还有OpenMP等替代品。
答案 4 :(得分:0)
我设法通过群组信号解决了这个问题:
for (int i = 0; i < N; i++)
{
if(fork() == 0)
{
/* save first process pid in shared memory */
if(localID == 0)
*sh_temp = getpid();
/* wait in all processes for shared memory with group id to be set */
while(*sh_temp == 0)
usleep(10000);
/* set group id to first process PID */
setpgid(getpid(), *sh_temp);
//some operations here
fprintf(stderr, "Process %d paused... W8ing for signal to resume\n", getpid());
raise(SIGSTOP);
//some operations I want all processes start at similiar time
}
}
if(parentPID == getpid())
{
fprintf(stderr, "Wake-up signal sent to group %ld.\n", *sh_temp);
killpg(*sh_temp, SIGCONT);
}
但是 - 如果有人有更好的解决方案,请发布。