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

调用fork()后write()写入文件意外出现"main"字符串的问题排查

问题分析与解决

你遇到的文件中出现"main"字符串的问题,根源在于write调用的长度参数错误,加上fork后父子进程的执行逻辑导致重复写入垃圾数据,具体拆解如下:

1. write长度参数超出字符串实际长度

你的两处write调用都指定了远大于字符串实际长度的字节数:

  • write(fd, "A Message from Child!\n", 35):该字符串(含换行符)实际仅22字节,但你指定写入35字节。write会从字符串起始位置读取35字节数据,超出部分会直接读取进程栈内存中的垃圾数据——而栈中恰好存在与"main"相关的内容(比如函数名、argv参数残留),这就导致无关的"main"被写入文件。
  • write(fd, "Message From parent!\n", 29):该字符串实际23字节,指定29字节同样会写入多余垃圾数据。

2. fork后的父子进程执行逻辑混乱

fork成功后,子进程会复制父进程的整个地址空间(包括打开的文件描述符fd):

  • 子进程会执行else分支的sleep和write,之后还会继续执行分支外的write(fd, "Message From parent!\n", 29)和close(fd)。
  • 父进程fork后(fChild为子进程PID,大于0),会跳过else分支,直接执行后续的write和close。

这就导致父子进程各自执行了两次write操作,垃圾数据被多次写入,最终出现多行"main"。

另外你的open调用存在隐患:使用O_CREAT标志时必须指定文件权限(第三个参数),否则会导致文件权限异常,甚至触发assert失败。

修复后的代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/types.h>
#include <string.h>

int main(int argc, char *argv[])
{
    // 给O_CREAT添加合法文件权限0644
    int fd = open("SomeFile.txt", O_WRONLY | O_CREAT | O_APPEND, 0644);
    assert(fd > -1);
    
    int fChild = fork();
    if(fChild < 0) {
        fprintf(stderr, "fork is failing !\n");
        exit(1); // fork失败后立即退出,避免后续错误执行
    } else if(fChild == 0) { // 明确标记子进程分支
        sleep(7);
        const char* child_msg = "A Message from Child!\n";
        write(fd, child_msg, strlen(child_msg));
        close(fd);
        exit(0); // 子进程执行完任务后退出,避免执行父进程后续代码
    } 
    // 父进程分支
    const char* parent_msg = "Message From parent!\n";
    write(fd, parent_msg, strlen(parent_msg));
    close(fd);
    return 0;
}

关键修复点

  • 使用strlen()获取字符串准确长度,彻底避免写入栈中垃圾数据。
  • 给open的O_CREAT标志补充合法权限参数(如0644)。
  • 子进程执行完任务后调用exit(0),切断与父进程后续代码的执行关联。
  • 明确区分父子进程分支,避免逻辑混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 05:22:52