我正在尝试将一个多进程的应用程序迁移到Docker中。不同的进程将被放置在不同的Docker容器中。
该应用程序使用共享内存来交换数据,使用信号量来进行同步。我已经重新编译了Docker,以便不使用IPC命名空间,并且我有效地通过sudo ipcs -m
检查了不同容器中共享内存缓冲区的可访问性。
问题是信号量无法正常工作。我编写了这些简单的程序来检查Docker中POSIX信号量的行为:
/* To be compiled with -lpthread */
#include <stdio.h>
#include <fcntl.h>
#include <semaphore.h>
int main(void) {
int ret, val;
sem_t * mySem;
printf("[ONE] Opening the semaphore...\n");
mySem = sem_open("sem1", O_CREAT, 0777, 0);
if (mySem == SEM_FAILED) {
printf("[ONE] Error on sem_open()\n");
return -1;
}
ret = sem_post(mySem);
getchar(); // Awful way to block execution of [ONE] for a while...
printf("[ONE] Waiting for [TWO]...\n");
ret = sem_wait(mySem);
printf("[ONE] Wait ended\n");
ret = sem_unlink("sem1");
printf("[ONE] Semaphore destroyed\n");
return 0;
}
第二个程序是:
/* To be compiled with -lpthread */
#include <stdio.h>
#include <fcntl.h>
#include <semaphore.h>
int main(void) {
int ret;
int val;
sem_t * mySem;
printf("[TWO] Opening the semaphore...\n");
mySem = sem_open("sem1", O_CREAT, 0777, 0);
if (mySem == SEM_FAILED) {
printf("[TWO] Error on sem_open()\n");
return -1;
}
ret = sem_getvalue(mySem, &val);
printf("[TWO] Semaphore's value is %d\n", val);
printf("[TWO] Waiting for [ONE]...\n");
ret = sem_wait(mySem);
printf("[TWO] Wait ended\n");
printf("[ONE] Doing sem_post() on semaphore...\n");
ret = sem_post(mySem);
ret = sem_close(mySem);
printf("[TWO] Semaphore closed\n");
return 0;
}
在两个程序中,我省略了许多控制语句,例如
if (ret != 0) {...}
,以保持问题的可读性。我在主机上运行了第一个程序,在Docker容器中运行了第二个程序。结果是第二个程序一直等待...
问题是:是否有可能以某种方式在Docker容器之间或容器和主机之间使用POSIX信号量?
sem_open()
的名称相同,第二个程序不会创建新的信号量,而是使用第一个应用程序创建的信号量。然后第二个应用程序等待由第一个应用程序使用sem_post()
解锁的信号量,以此类推... - Manuel Durandoshmget()
等方式获取共享内存。 - Manuel Durando