Проблема сложнее, но я хочу понять более простой пример. Допустим, у меня есть 3 процесса, и я хочу, чтобы процесс 3 запускался раньше процесса 1. Как мне это сделать? Или возможно ли это сделать?
#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;
}
Это результат, который я получаю:
Process 1 started.
Process 3 started.
Process 2 started.
Process 2 completed its work.
Это похоже на бесконечный цикл: процесс 1 и процесс 3 не завершаются.
Вам необходимо использовать «общий» семафор для обмена/сигнализации между процессами. Необщий семафор (например, который вы используете) может синхронизировать потоки только в одном процессе.
Чтобы создать общий семафор, вам необходимо выделить его в общей памяти, что немного сложно. Самый простой способ — использовать
#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);
}
Это немного неэффективно, поскольку для семафора выделяется целая страница (обычно 4096 байт), большая часть которой тратится впустую (mmap округлит запрошенный размер до кратного размера страницы).
Если вам нужно несколько семафоров, вы можете выделить их в виде массива одним вызовом mmap. Если вам нужно больше общей памяти (например, буферы для связи между процессами), вы можете собрать все необходимое в одну большую структуру и выделить ее с помощью mmap
Нужно ли мне импортировать некоторые библиотеки? Я получаю такие ошибки, как: PROT_READ, PROT_WRITE и т. д. не определено.
@DenisAndris - да, вам понадобится #include <sys/mman.h>
, чтобы получить все необходимые объявления для mmap. Используйте man mmap
на терминале, чтобы просмотреть документацию по mmap.
Отвечает ли это на ваш вопрос? Как использовать семафоры POSIX в разветвленных процессах на C?