等待所有进程到达程序中的某个点,然后继续

时间:2015-06-04 11:38:34

标签: c linux synchronization fork

我有一个应用程序,它通过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

我不想让任何孩子退出。

5 个答案:

答案 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(进程间通信)。这取决于您需要发送什么样的信息,大小等等。过程信号也是控制过程的一种方式。

以下是一些可以帮助您入门的资源:

  1. 就个人而言,我喜欢Beej指南,这些指南非常棒,清晰,简洁且免费! http://beej.us/guide/bgipc/
  2. CodeSourcery LLC还提供高级Linux编程。 http://www.advancedlinuxprogramming.com/
  3. 当然,一旦你掌握了一些基本概念,你就可以更具体地查找http://stackoverflow.com,即就在这里: - )

答案 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);
 }

但是 - 如果有人有更好的解决方案,请发布。