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

wait()触发Interrupted system call异常:多进程共享内存场景排查请求

问题排查:wait()返回"Interrupted system call"偶现问题

问题描述

原本预期wait()函数会等待所有子进程执行完毕,但实际运行中该函数偶现返回-1,提示"Interrupted system call"。调试模式下运行无异常,曾怀疑问题与共享内存相关。

代码示例

#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <unistd.h>
#include <errno.h>

#define PROCESSES 3

struct shdata
{
    int x;
};

void childf(int shared_memory, int index)
{
    // connect shared memory
    struct shdata* shm = (struct shdata*)shmat(shared_memory, NULL, 0);
    if(shm == (void*)-1)
    {
        perror("shmat");
        exit(0);
    }
    
    // initialize x as 0
    if(index == 0)
    {
        shm->x = 0;
    }
    
    // increment x
    shm->x++;
    
    //show x
    printf("Proces %d: x = %d\n", index, shm->x);
    
    // disconnect shared memory
    if(shmdt(shm) == -1)
    {
        perror("shmdt");
        exit(0);
    }
    
    // end child process
    exit(0);
}

int main(int argc, const char * argv[]) {
    
    // create shared memory
    int shared_memory = shmget(IPC_PRIVATE, 4096, 0600 | IPC_CREAT | IPC_EXCL);
    if(shared_memory == -1)
    {
        perror("shmget");
        return 1;
    }
    
    // create child processes
    for (int i = 0; i < PROCESSES; i++)
    {
        int pid = fork();
        if(pid == -1)
        {
            perror("fork");
            return 5;
        }
        if(pid == 0)
        {
            childf(shared_memory, i);
        }
    }
    
    // wait for child processes
    for(int i = 0; i < PROCESSES; i++)
    {
        int wait_res = wait(NULL);
        if(wait_res < 0)
        {
            perror("wait");
            return 6;
        }
    }
    
    // delete shared memory
    int delete_memory = shmctl(shared_memory, IPC_RMID, NULL);
    if(delete_memory == -1)
    {
        perror("shmctl");
        return 4;
    }
    
    return 0;
}

实际输出

Proces 0: x = 1 Proces 1: x = 2 Proces 2: x = 3 wait: Interrupted system call Program ended with exit code: 6

预期输出

Proces 0: x = 1 Proces 1: x = 2 Proces 2: x = 3 Program ended with exit code: 0

问题原因与解决方案

原因分析

这个问题和共享内存无关,核心原因是**wait()被信号中断**。当进程处于wait()这类阻塞系统调用时,如果收到一个未被忽略的信号,系统调用会被强制打断,返回-1,同时errno被设置为EINTR(对应提示的"Interrupted system call")。

调试模式下无异常,是因为调试器会接管进程的信号处理,或者运行节奏变慢,未触发导致中断的信号,所以问题不会显现。

解决方案

标准处理方式是捕获EINTR错误,重新调用wait()——因为系统调用被中断不代表没有子进程需要等待,只是被信号打断了,重试即可。

修改main()中等待子进程的代码段:

// wait for child processes
int wait_count = 0;
while (wait_count < PROCESSES) {
    int wait_res = wait(NULL);
    if (wait_res < 0) {
        if (errno == EINTR) {
            // 被信号中断,重试wait调用
            continue;
        }
        perror("wait");
        return 6;
    }
    wait_count++;
}

也可以使用waitpid(-1, NULL, 0)替代wait(),处理逻辑一致,同样需要捕获EINTR重试。

内容的提问来源于stack exchange,提问作者Єгорій

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:35:28