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

使用atoi()获取整数异常:父进程PID跨进程传递失败问题

问题:父进程PID传递给子进程后无法正确解析

我正在编写一个简单的C程序,旨在将父进程的PID传递给子进程并打印,但使用atoi()函数后无法得到正确的父进程PID,不清楚问题出在哪里。我了解到atoi()是ASCII转整数函数,不确定是否使用正确。我知道命令行参数必须以字符串形式传递。刚学习C语言,若问题浅显还请见谅。

父进程代码

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

#define COUNT 1

int pfd[2];

int main()
{
    pid_t process_id;

    char pipeReadstr[11];
    char str1_pid[10];

    // Set up the pipe
    pipe(pfd);
    
    sprintf(str1_pid, "%d", getpid());

    //Set up the read file descriptor
    sprintf (pipeReadstr, "%d", pfd[0]);

    process_id = fork();

    if (process_id == 0)
    {
        close(pfd[1]);//Close the write end of pipe 0
        execl("../receiveVar/receiveVar.exe", "receiveVar", pipeReadstr, 
              (char *)NULL);
    }
    sleep(2);

    // Passing str1 to the write end of pipe 0, then close write and read ends
    write(pfd[1], str1_pid, strlen(str1_pid));
    close(pfd[1]);
    close(pfd[0]);
}

子进程代码

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

#define READ_BLOCK_SIZE 10

int main(int argc, char *argv[])
{
    pid_t str = getpid();

    char readBuffer[READ_BLOCK_SIZE+1];
    ssize_t bytesRead;

    int readFd;

    readFd = atoi(argv[1]);
    bytesRead = read(readFd, readBuffer, READ_BLOCK_SIZE);

    while (bytesRead > 0)
    {
        readBuffer[bytesRead] = '\0';
        printf("Child Process: Received parent process PID: %d. Child process read %li bytes.\n", readFd, bytesRead);
        printf("Child Process PID: %d\n", str);
        bytesRead = read(readFd, readBuffer, READ_BLOCK_SIZE);
    }
    close(readFd);
}

问题分析与修复

你的代码核心问题是子进程打印了错误的变量:你在printf里输出的是readFd(管道的文件描述符),而不是从管道读取到的父进程PID(存储在readBuffer中),这直接导致你看到的不是父PID而是管道FD。atoi()的使用是正确的,但你用错了解析的对象。

修复后的子进程代码

修改printf部分,解析readBuffer中的内容作为父PID:

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

#define READ_BLOCK_SIZE 10

int main(int argc, char *argv[])
{
    pid_t child_pid = getpid();

    char readBuffer[READ_BLOCK_SIZE+1];
    ssize_t bytesRead;

    int readFd = atoi(argv[1]);
    bytesRead = read(readFd, readBuffer, READ_BLOCK_SIZE);

    while (bytesRead > 0)
    {
        readBuffer[bytesRead] = '\0';
        // 解析readBuffer中的内容为父进程PID
        printf("Child Process: Received parent process PID: %d. Child process read %li bytes.\n", atoi(readBuffer), bytesRead);
        printf("Child Process PID: %d\n", child_pid);
        bytesRead = read(readFd, readBuffer, READ_BLOCK_SIZE);
    }
    close(readFd);
    return 0;
}

可选优化(提升父进程可靠性)

去掉sleep(2)的不可靠等待,改为等待子进程结束并确保管道写入完整:

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

int pfd[2];

int main()
{
    pid_t process_id;

    char pipeReadstr[11];
    char str1_pid[10];

    pipe(pfd);
    
    sprintf(str1_pid, "%d", getpid());
    sprintf(pipeReadstr, "%d", pfd[0]);

    process_id = fork();

    if (process_id == 0)
    {
        close(pfd[1]);
        execl("../receiveVar/receiveVar.exe", "receiveVar", pipeReadstr, (char *)NULL);
        // 处理execl失败的情况
        perror("execl failed");
        exit(EXIT_FAILURE);
    }

    close(pfd[0]);
    // 写入时包含字符串终止符,确保子进程读取完整
    write(pfd[1], str1_pid, strlen(str1_pid) + 1);
    close(pfd[1]);

    // 等待子进程结束,避免僵尸进程
    wait(NULL);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:30:22