You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下C语言进程同步问题:进程3先于进程1执行及异常排查

进程启动顺序控制问题:让进程3先于进程1执行

现有3个进程,想要让进程3先于进程1启动执行,是否可行?该如何实现?

我尝试编写了如下C语言代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <semaphore.h>

int main() {
    sem_t semaphore;

    // 初始化信号量,初始值为0
    if (sem_init(&semaphore, 0, 0) == -1) {
        perror("Semaphore initialization failed");
        exit(EXIT_FAILURE);
    }

    // 创建子进程1
    if (fork() == 0) {
        // 子进程1(Process 1)开始执行
        printf("Process 1 started.\n");
        // 等待进程3的信号
        sem_wait(&semaphore); 
        printf("Process 1 completed its work.\n");
        exit(0);
    }

    // 创建子进程2
    if (fork() == 0) {
        // 子进程2(Process 2)开始执行
        printf("Process 2 started.\n");
        printf("Process 2 completed its work.\n");
        exit(0);
    }

    // 创建子进程3
    if (fork() == 0) {
        // 子进程3(Process 3)开始执行
        printf("Process 3 started.\n");
        // 发送信号让进程1开始执行
        sem_post(&semaphore);
        exit(0);
    }

    wait(NULL);
    wait(NULL);
    wait(NULL);

    // 销毁信号量
    sem_destroy(&semaphore);

    return 0;
}

运行后得到如下输出:

Process 1 started.
Process 3 started.
Process 2 started.
Process 2 completed its work.

程序陷入了阻塞,进程1和进程3都没有终止。


问题原因分析

核心问题在于信号量的进程共享属性未正确设置:

  • sem_init函数的第二个参数pshared,设为0时信号量仅能被当前进程的线程共享;设为1时,才能在父子进程间共享。
  • 你代码里用了0,导致进程3调用sem_post时,操作的是自己进程空间内的信号量副本,根本无法唤醒进程1中等待的信号量,所以进程1会一直卡在sem_wait处,父进程的wait也会一直等待未终止的进程,看起来像无限循环。

修正方案

把sem_init的第二个参数改为1,让信号量在进程间共享,修正后的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <semaphore.h>

int main() {
    sem_t semaphore;

    // 初始化进程间共享的信号量,初始值为0
    if (sem_init(&semaphore, 1, 0) == -1) {
        perror("Semaphore initialization failed");
        exit(EXIT_FAILURE);
    }

    // 创建子进程1
    if (fork() == 0) {
        printf("Process 1 started.\n");
        sem_wait(&semaphore); 
        printf("Process 1 completed its work.\n");
        exit(0);
    }

    // 创建子进程2
    if (fork() == 0) {
        printf("Process 2 started.\n");
        printf("Process 2 completed its work.\n");
        exit(0);
    }

    // 创建子进程3
    if (fork() == 0) {
        printf("Process 3 started.\n");
        sem_post(&semaphore);
        printf("Process 3 completed its work.\n");
        exit(0);
    }

    // 等待所有子进程退出
    wait(NULL);
    wait(NULL);
    wait(NULL);

    sem_destroy(&semaphore);

    return 0;
}

预期运行效果

修正后运行,会得到类似如下的输出(进程2的启动顺序可能和3、1有波动,但进程1一定会在进程3发送信号后才完成工作):

Process 2 started.
Process 2 completed its work.
Process 3 started.
Process 3 completed its work.
Process 1 started.
Process 1 completed its work.

内容的提问来源于stack exchange,提问作者Denis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 19:23:29