Синхронизация процессов в C, Linux

Проблема сложнее, но я хочу понять более простой пример. Допустим, у меня есть 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 не завершаются.

Отвечает ли это на ваш вопрос? Как использовать семафоры POSIX в разветвленных процессах на C?

Tsyvarev 04.05.2024 14:31
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
61
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам необходимо использовать «общий» семафор для обмена/сигнализации между процессами. Необщий семафор (например, который вы используете) может синхронизировать потоки только в одном процессе.

Чтобы создать общий семафор, вам необходимо выделить его в общей памяти, что немного сложно. Самый простой способ — использовать

#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 и т. д. не определено.

Denis 04.05.2024 04:16

@DenisAndris - да, вам понадобится #include <sys/mman.h>, чтобы получить все необходимые объявления для mmap. Используйте man mmap на терминале, чтобы просмотреть документацию по mmap.

Chris Dodd 04.05.2024 04:28

Другие вопросы по теме