是否有可能以某种方式在Docker容器之间或容器与主机之间使用POSIX信号量?

我正在尝试将多进程应用程序迁移到Docker。 不同的进程将被放置在不同的Docker容器中。

应用程序使用共享内存交换数据和信号量进行同步。 为了不使用IPC命名空间,我已经重新编译了Docker,并且使用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; } 

第二个scheme是:

 /* 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信号量?

我解决了这个问题,在这个问题中解释了在Docker容器之间使用共享内存。

以下代码是本教程的修改版本。

文件 server.c

 /* To be compiled with -lpthread */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/shm.h> #include <fcntl.h> #include <semaphore.h> #define SHM_SIZE 1000 int main(void) { int shmid; key_t key; char *shm; sem_t * mySem; /* We'll name our shared memory segment "5678" */ key = 5678; /* Create the segment.*/ if ((shmid = shmget(key, SHM_SIZE, IPC_CREAT | IPC_EXCL | 0666)) < 0) { perror("shmget"); exit(1); } /* Now we attach the segment to our data space */ if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) { perror("shmat"); exit(1); } /* Create a new semaphore */ mySem = sem_open("sem1", O_CREAT, 0777, 0); /* Copy the semaphore on the shared memory segment */ memcpy(shm, mySem, sizeof(*mySem)); /* Do stuff ... */ /* REMEMBER TO USE THE SHARED MEMORY SEGMENT */ /* AND NOT THE LOCAL mySem, USE (sem_t*)shm INSTEAD! */ /* Finally, we wait until the other process * changes the first character of our memory * to '*', indicating that it has read what * we put there. */ while (*shm != '*') sleep(1); /* Mark the memory segment to be destroyed */ shmctl(shmid, IPC_RMID, NULL); /* Detach of the memory segment */ shmdt(&shm); sem_unlink("sem1"); return 0; } 

文件 client.c

 /* To be compiled with -lpthread */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/ipc.h> #include <sys/shm.h> #include <fcntl.h> #include <semaphore.h> #define SHM_SIZE 1000 int main(void) { int shmid; key_t key; char *shm; int ret, val; key = 5678; if ((shmid = shmget(key, SHM_SIZE, 0666)) < 0) { perror("shmget"); exit(1); } if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) { perror("shmat"); exit(1); } /* SEMAPHORE IS IN THE SHARED MEMORY SEGMENT */ /* USE (sem_t*)shm TO ACCESS IT */ *shm = '*'; shmdt(&shm); sem_close("sem1"); return 0; } 

代码示例由于可读性目的而错过了许多控制。

我在主机上运行服务器,Docker容器中的客户端,并检查信号量是否可以从两个进程访问。

Interesting Posts