2

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

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

问题 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");
4

2 回答 2

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 是缺少包含。)

于 2013-04-09T17:33:41.107 回答
0

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

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

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

于 2013-04-09T17:22:42.800 回答