c - 如何通过信号量同步N个进程互相等待

标签 c linux process semaphore

Linux,C.

我必须同步从一个父进程派生的 N 个进程。

每个进程都需要等到所有其他进程都完成了一个任务,然后它们才能同时转移到第二个任务。

我正在考虑实现一个信号量,但我真的不知道是哪种类型以及如何以有效的方式实现它。

任何人都可以告诉我这样做的方法吗?

有没有人能解决这个问题?

这是我想要实现的一些伪代码:

for (int i = 0; i < init_people; ++i) {

    switch (pids[i] = fork()) {
        case -1:
            exit(1);
            break;
        case 0:
            switch (i % 2) {
                case 0:

                    /*Here is where one of the processes starts and 
                    does his task*/ 

                    execve("./A",args,NULL);

                    /*Here is where it stops and waits for all the 
                    other processes to complete the task*/

                    break;

                case 1:

                    /*Here is where one of the processes starts and 
                    does his task*/

                    execve("./B",args,NULL);
                    break;

                    /*Here is where it stops and waits for all the 
                    other processes to complete the task*/

                default:
                    break;
            }
            exit(0);
            break;

        default:
            waitpid(pids[i], &returnStatus, 0);
            break;
    }
}

最佳答案

Every process needs to wait until all other processes have completed a task before they can all move to the second task simultaneously.

I was thinking about implementing a semaphore

是的,您可以使用 System V semaphore有效的方式实现它被初始化为进程数 N,当它的第一个任务完成并等待变为零时,每个进程递减,然后再继续第二个任务。我完成了(并根据需要更改了)您的伪代码。

#define _XOPEN_SOURCE
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

int main()
{
    #define N   2
    const int init_people = N;
    pid_t pids[N];
    char *task[N] = { "./A 1", "./B 1" };
    char *second_task[N] = { "./A 2", "./B 2" };
    int sem = semget(IPC_PRIVATE, 1, S_IRWXU);  // create a semaphore
    semctl(sem, 0, SETVAL, init_people);        // initialize the value to N
    for (int i = 0; i < init_people; ++i)
        switch (pids[i] = fork())
        {
        case -1:
            exit(1);
        case 0:
            /*Here is where each of the processes starts and
            does his task*/ 
            system(task[i]);    // execve wouldn't return
            /*Here is where it stops and waits for all the 
            other processes to complete the task*/
            // decrement the semaphore value
            semop(sem, &(struct sembuf){.sem_op=-1}, 1);
            // wait until value is zero
            while (semop(sem, &(struct sembuf){}, 1) < 0)
                if (errno != EINTR) perror("semop"), exit(1);
            /*Here all move to the second task simultaneously*/
            system(second_task[i]);
            exit(0);
        }
    do ; while (wait(NULL) > 0);
    if (errno != ECHILD) perror("wait");
    semctl(sem, 0, IPC_RMID);   // remove the semaphore
}

关于c - 如何通过信号量同步N个进程互相等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47663551/

相关文章:

c# - 如何从接受输入的 C# 表单应用程序打开 cmd

c - Ansi C 动态包含

c - 当路径长于 PATH_MAX 时从文件描述符获取路径

c - 错误: c code: expression must be a modifiable lvalue

linux - 使用 Unix 排序对多个键进行排序——错误?

c - unix域套接字VS命名管道?

c++ - 什么时候全局变量实际上被认为是好的/推荐的做法?

python - 有没有办法在设置大小参数时使 buffer() 可写而不进行复制?

perl - 如何在 Perl 中触发并忘记一个进程?

Linux 文件和进程级 I/O 性能指标