Is it possible in some way to use POSIX semaphores between Docker containers or between a container and the host?
I solved the problem using shared memory between Docker containers as explained in this question.
The following code is a modified version of this tutorial.
File 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 1000int 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;}
File 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 1000int 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;}
The code examples miss lots of controls due to readability purposes.
I run the server on the host machine, the client inside a Docker container and checked that the semaphore was accessible from both processes.