如何通过子进程之间的共享内存共享信号量?

Posted

技术标签:

【中文标题】如何通过子进程之间的共享内存共享信号量?【英文标题】:How do I share a semaphore through shared memory between child processes? 【发布时间】:2014-11-14 04:18:33 【问题描述】:

我正在尝试使用进程重现 MapReduce。我使用 shmget() 在父进程中分配共享内存,因此每个子进程都应该可以访问它。假设这块内存存储了一个标志和一个信号量。第一个完成集合的子节点等待信号量(其初始值为 1),设置标志,然后运行 ​​reduce 方法。因此,当其他子进程发现该标志已设置时,它们应该各自退出。我没有得到预期的行为,如果有人能告诉我下面提供的代码中发生了什么,以及它与我想要完成的内容有何不同,我将不胜感激。

在 sem_init 之后检查 errno 为我提供了 ENOSYS,根据文档,这是正确的,因为我将 pshared 设置为 1。

int map_reduce(int num_proc)
    int i, pid, id, sem_ret, sem_count;
    size_t index, size = 1 + sizeof(sem_t);
    key_t key = IPC_PRIVATE;
    id = shmget(key, size, IPC_CREAT | SHM_W | SHM_R);
    void *addr = shmat(id, NULL, 0);

    *((char *)addr) = 0;
    sem_t *sem = (sem_t *)((char *)addr + 1);
    sem_count = 1;
    sem_ret = sem_init(sem, 1, sem_count);
    printf("%d \n", errno == ENOSYS); // this is true

    for(i = 0; i < num_proc; i++)
        pid = fork();
        if(pid == 0)
            map();
            sem_ret = sem_wait(sem);
            if(*((char *)addr) == 0)
                *((char *)addr) = 1;
                reduce();
            
            sem_ret = sem_post(sem);
            exit(0);
        
    

    while(wait(NULL) > 0);
    struct shmid_ds buf;
    key = shmctl(id, IPC_RMID, &buf);
    return 0;

这是我运行一个只调用 map_reduce(5) 的实例得到的结果。 map 和 reduce 也只是打印出 pid。

pid: 19813 mapping
pid: 19814 mapping
pid: 19815 mapping
pid: 19816 mapping
pid: 19814 reducing
pid: 19812 reducing
pid: 19815 reducing

【问题讨论】:

您确定ENOSYS 是预期的吗?根据我刚刚阅读的手册页,ENOSYS 表示“此实现不支持 sem_init” 【参考方案1】:

ENOSYS 表示

The function sem_init() is not supported by this implementation.

pshared is nonzero, but the system does not support process-shared semaphores.

换句话说,您的系统不支持共享信号量,因此您不能使用信号量来完成您尝试跨进程边界的操作。

【讨论】:

以上是关于如何通过子进程之间的共享内存共享信号量?的主要内容,如果未能解决你的问题,请参考以下文章

使用共享内存(mmap)和信号量的进程间通信

如何在 c 中使用 posix 命名信号量和 Linux 上两个进程之间的共享内存?

深入详解Linux进程间通信之共享内存(Shared Memory)+信号量同步

深入详解Linux进程间通信之共享内存(Shared Memory)+信号量同步

深入详解Linux进程间通信之共享内存(Shared Memory)+信号量同步

进程通信——管道消息队列共享内存信号量