代码之家  ›  专栏  ›  技术社区  ›  Denis

在C、linux中同步进程

  •  0
  • Denis  · 技术社区  · 1 年前

    这个问题更难,但我想理解一个更容易的例子。 假设我有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不会终止。

    1 回复  |  直到 1 年前
        1
  •  3
  •   Chris Dodd    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