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

信号处理程序中fork()的父子进程同步安全实现咨询

信号处理程序中fork后父子进程同步的安全实现方式

你的核心问题是信号处理程序中不能使用普通互斥锁(这类锁操作不在异步安全函数列表里),但要实现父进程完成任务后子进程再执行后续逻辑,下面是两种可靠的异步安全实现方式:

方法一:用匿名管道同步

管道的read()和write()属于异步安全函数,可在信号处理程序里安全使用,实现逻辑如下:

  1. 父进程在fork()前创建一对匿名管道
  2. 父进程分支先执行build_house(),完成后往管道写一个标记数据(比如一个字节)
  3. 子进程分支先执行play_in_yard(),然后从管道读数据——读操作会阻塞直到父进程写完,之后再执行enter_house()

示例代码:

#include <unistd.h>
#include <stdlib.h>

void signal_handler(int sig) {
    int pipefd[2];
    if (pipe(pipefd) == -1) {
        _exit(1);
    }

    pid_t child_pid = fork();
    if (child_pid != 0) {
        // 父进程:关闭读端
        close(pipefd[0]);
        build_house();
        // 写一个字节标记任务完成
        char dummy = '1';
        write(pipefd[1], &dummy, 1);
        close(pipefd[1]);
    } else {
        // 子进程:关闭写端
        close(pipefd[1]);
        play_in_yard();
        // 等待父进程的信号,阻塞直到读到数据
        char dummy;
        read(pipefd[0], &dummy, 1);
        close(pipefd[0]);
        enter_house();
        _exit(0);
    }
}

方法二:用用户自定义信号同步

kill()和sigwait()属于异步安全操作,也能实现同步:

  1. 父进程fork()后,完成build_house()时,用kill()给子进程发送自定义信号(比如SIGUSR1)
  2. 子进程先执行play_in_yard(),然后通过sigwait()等待信号,收到后执行enter_house()

示例代码:

#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

void signal_handler(int sig) {
    pid_t child_pid = fork();
    if (child_pid != 0) {
        // 父进程
        build_house();
        // 给子进程发信号
        kill(child_pid, SIGUSR1);
        wait(NULL);
    } else {
        // 子进程:设置信号掩码,只等待SIGUSR1
        sigset_t set;
        sigemptyset(&set);
        sigaddset(&set, SIGUSR1);
        // 阻塞等待信号
        int sig_caught;
        sigwait(&set, &sig_caught);
        
        play_in_yard();
        enter_house();
        _exit(0);
    }
}

注意事项

  • 信号处理程序里绝对不能调用非异步安全函数,错误处理尽量用_exit()而不是exit()
  • 用管道时要注意关闭未使用的文件描述符,避免资源泄漏
  • 用信号时要注意信号掩码的设置,避免其他信号干扰等待逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:35:25