【问题标题】:How to use named semaphore from child如何使用来自孩子的命名信号量
【发布时间】:2013-03-29 19:07:33
【问题描述】:

所以基本上我想在子进程创建后暂停一点,这样父进程就可以在共享内存中为它准备一些数据。我正在尝试使用信号量,如下所示: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");

【问题讨论】:

  • 名称前面的/ 是有意的吗?
  • @bash.d,是的,我在一个例子中发现了这一点,并发现这并不重要。我更改了信号量的名称,但问题仍然存在。
  • 可能是并发问题? sem_open 会立即阻塞还是失败?
  • 如果strerror() 返回int,这意味着(1)你忽略了编译器警告和(2)你忘了#include &lt;string.h&gt;
  • @gg.kaspersky 抱歉,没注意到它超载了。关于您的问题,您是否尝试过在删除信号量之前在主进程中等待?也许它在孩子有机会使用它之前就被删除了。

标签: c linux fork semaphore


【解决方案1】:

您根本不需要孩子调用sem_open() — 他们可以在继承的sem_t 句柄上简单地使用sem_wait()

您可能希望将信号量限制为仅限于您的“工作人员”。在这种情况下,父级应使用限制性权限以独占方式打开信号量 (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 是缺少包含。)

【讨论】:

    【解决方案2】:

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

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

    2) 错过了#include &lt;string.h&gt;

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 2012-08-02
      • 2015-05-24
      • 2016-11-01
      • 1970-01-01
      • 2020-08-07
      • 1970-01-01
      • 2012-08-01
      相关资源
      最近更新 更多