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