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

C语言通过SIGSTOP、SIGCONT控制子进程按序循环执行问题

现有代码问题
  • 进程创建与调度耦合:父进程每创建一个子进程就立刻执行调度、阻塞等待子进程退出,此时后续子进程尚未创建,且子进程为死循环逻辑,waitpid会永久阻塞导致流程卡死。
  • 调度逻辑仅执行一轮:调度代码嵌套在子进程创建的循环内,跑完p0到p4的单次序列后就无后续逻辑,无法实现无限循环调度。
  • 初始状态不符合要求:子进程创建后虽先收到SIGSTOP,但立刻被发送SIGCONT唤醒,无法做到启动时所有子进程默认停止。
  • 信号注册位置错误:signal(SIGCONT, &handler)写在父进程的fork循环内,子进程未注册对应信号处理,且父进程注册该信号无实际作用。
修复思路
  • 拆分创建和调度逻辑:先完成所有5个子进程的创建,每创建一个就立刻发送SIGSTOP使其停止,保证所有子进程创建完成后全处于停止状态,满足初始状态要求。
  • 独立实现循环调度:维护当前运行子进程的索引,每次仅唤醒当前索引对应的子进程,运行指定时长后发送SIGSTOP将其停止,再更新索引为下一个值,通过取模操作实现索引循环。
  • 清理无效逻辑:去掉会永久阻塞的waitpid调用,将信号处理函数注册到子进程逻辑内。
修复后可运行代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>

#define N 5

// 子进程SIGCONT信号处理函数
void cont_handler(int sig) {
    if (sig == SIGCONT) {
        printf("子进程收到继续运行信号\n");
    }
}

int main() {
    int pid[N];
    int cur_proc = 0; // 记录当前调度运行的子进程索引

    // 第一步:创建所有子进程,创建后立刻停止,保证初始全停
    for (int i = 0; i < N; i++) {
        pid[i] = fork();
        if (pid[i] == 0) {
            // 子进程执行逻辑
            signal(SIGCONT, cont_handler);
            while (1) {
                printf("当前运行子进程 p%d\n", i);
                usleep(50000); // 每50ms打印一次,避免输出刷屏
            }
            exit(0);
        }
        // 父进程给刚创建的子进程发停止信号
        kill(pid[i], SIGSTOP);
    }

    // 第二步:无限循环轮转调度
    while (1) {
        // 唤醒当前索引的子进程
        kill(pid[cur_proc], SIGCONT);
        // 让当前子进程运行1秒
        sleep(1);
        // 停止当前运行的子进程
        kill(pid[cur_proc], SIGSTOP);
        // 更新下一个调度的子进程索引,到末尾后回到0
        cur_proc = (cur_proc + 1) % N;
    }

    // 优雅退出逻辑(正常运行不会走到这里,可加SIGINT捕获触发)
    for (int i = 0; i < N; i++) {
        kill(pid[i], SIGKILL);
        waitpid(pid[i], NULL, 0);
    }
    return 0;
}
代码说明
  • 初始状态符合要求:所有子进程创建完成后第一时间被SIGSTOP暂停,调度逻辑启动前无任何运行中的子进程。
  • 单进程运行保证:每次调度仅给当前索引的子进程发送SIGCONT,运行到时间后立刻发SIGSTOP暂停,任意时刻最多只有一个子进程处于运行状态。
  • 循环调度符合要求:通过cur_proc = (cur_proc + 1) % N实现索引轮转,固定按p0→p1→p2→p3→p4→p0的顺序循环调度。
  • 编译运行命令:gcc schedule.c -o schedule && ./schedule,运行后可观察到子进程按固定顺序轮转输出,按Ctrl+C可终止程序。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 00:33:24