The problem is more difficult, but I want to understand an easier example. Let's say I have 3 processes, and I want process 3 to start before process 1, how can I do it? Or, is it possible to do it?
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <semaphore.h>
int main() {
sem_t semaphore;
// Initialize semaphore with initial value 0
if (sem_init(&semaphore, 0, 0) == -1) {
perror("Semaphore initialization failed");
exit(EXIT_FAILURE);
}
// Create child process 1
if (fork() == 0) {
// Child process 1 (Process 1) starts here
printf("Process 1 started.\n");
// Wait for signal from Process 3
sem_wait(&semaphore);
printf("Process 1 completed its work.\n");
exit(0);
}
// Create child process 2
if (fork() == 0) {
// Child process 2 (Process 2) starts here
printf("Process 2 started.\n");
printf("Process 2 completed its work.\n");
exit(0);
}
// Create child process 3
if (fork() == 0) {
// Child process 3 (Process 3) starts here
printf("Process 3 started.\n");
// Signal Process 1 to start
sem_post(&semaphore);
exit(0);
}
wait(NULL);
wait(NULL);
wait(NULL);
// Destroy semaphore
sem_destroy(&semaphore);
return 0;
}
This is the output I get:
Process 1 started.
Process 3 started.
Process 2 started.
Process 2 completed its work.
It's like running into an infinite loop, process 1 and process 3 do not terminate.
You need to use a "shared" semaphore to share/signal between processes. An unshared semaphore (like you're using) can only synchronize threads in a single process.
To create a shared semaphore, you need to allocate it in shared memory, which is a bit tricky. The easiest way is to use
#include <sys/mman.h>
:
sem_t *semaphore = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_ANONYMOUS, -1, 0);
if (semaphore == MAP_FAILED || sem_init(semaphore, 1, 0) == -1) {
perror("Semaphore initialization failed");
exit(EXIT_FAILURE);
}
This is a bit ineffiecent as it allocates a whole page (usually 4096 bytes) for the semaphore, wasting most of it (mmap will round up the requested size to a multiple of the page size).
If you need multiple semaphores, you can allocate them as an array with a single call to mmap. If you need more shared memory (such as buffers to communicate between the processes), you can gather all the things you need together into a single large struct and allocate that with mmap