调用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
相关产品推荐
相关产品推荐

