如何使用来自child的命名信号量

时间:2013-04-07 19:08:42

标签: c linux fork semaphore

所以基本上我想在创建后暂停一下子进程,这样父进程就会在共享内存中为它准备一些数据。我正在尝试使用信号量,如下所示:How to share semaphores between processes using shared memory

问题nr 1 :孩子无法打开信号量。

问题nr 2 :strerror返回一个int,但是man strerror明确表示它返回一个char *。

要避免“你尝试过什么”:

sem = sem_open("/semaphore", O_CREAT, 0644, 0);    

for (i = 0; i < num; i++)                                        
{   
    pid = fork();                                                               

    if (pid == 0)                                                               
    {   
        sem = sem_open("/semaphore", 0);                                        
        if (sem == SEM_FAILED)                                                  
        {   
            printf( "Error : %d\n", strerror(errno ));
            exit(0);                                                            
        }
        sem_wait(sem);   
        exit(0);                                                                
    }                                                                                                                       
}

prepare_data_for_child_processes();

for (i = 0; i < mpi_comm_world->np; i++)
    sem_post(sem);

sem_close(sem);
sem_unlink("/semaphore");

2 个答案:

答案 0 :(得分:1)

您根本不需要孩子拨打sem_open() - 他们只需sem_wait()继承sem_t句柄。

您可能希望将信号量限制为仅限“工作人员”。在这种情况下,父级应该使用限制性权限独占打开信号量(O_EXCL),然后立即取消链接。这样可以防止诚实的错误破坏你的信号量状态(但不会防止恶意程序):

...
sem = sem_open("/semaphore", O_CREAT|O_EXCL, 0644, 0); /* Note O_EXCL */
sem_unlink("/semaphore");

for (i = 0; i < num; i++) {
  if (fork() == 0) {
    sem_wait(sem);
    /* Do some work */
    exit(0);
  }
}

prepare_data_for_child_processes();

for (i = 0; i < mpi_comm_world->np; i++)
    sem_post(sem);

sem_close(sem);

现在,如果您的实现支持它,您应该在共享内存中sem_init(1, 0)。这将为您提供一个真正的匿名信号量,仅限于您的工作人员。

(并且,是的,问题#2是一​​个缺失的包括。)

答案 1 :(得分:0)

所以,我从评论中得到了答案:

1)原来这是一个竞争条件问题:父进程在任何孩子打开之前删除了信号量。

2)错过了#include <string.h>