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

C多进程程序通过shell重定向文件输入时输出乱码问题

问题根因分析
  • 核心原因:C标准库stdin默认采用全缓冲模式,父子进程的用户态缓冲区独立
    你通过管道将两个输入文件的内容合并传给程序时,第一个拿到互斥锁的进程(通常是父进程)调用scanf读前5个值时,C标准库会一次性把管道内所有可用数据全部读到自己进程的用户态stdin缓冲区中,不会只读刚好5个int对应的数据。
    而fork()生成的子进程拥有独立的地址空间,父进程缓冲区里剩下的输入内容(也就是input2.txt的内容)无法被子进程访问到,子进程调用scanf时读不到有效输入,scanf执行失败,未初始化的栈变量value的随机垃圾值就被写到了输出文件中,也就是你看到的乱码负数。
    互斥锁仅能保证两个进程不会同时执行读写逻辑,无法解决用户态缓冲跨进程不可见的问题。
  • 次要bug:互斥锁销毁逻辑错误
    你初始化的是存在共享内存里的shared_mutex,但程序末尾销毁的是从未初始化过的全局变量mutex,会触发未定义行为。
修复方案
  1. 禁用stdin的用户态缓冲,让每次读取直接从内核管道获取数据,内核态的管道数据是所有进程共享的。在main函数最开头加入以下代码:
setvbuf(stdin, NULL, _IONBF, 0);
  1. 修正互斥锁销毁逻辑,改为销毁shared_mutex:
// 原错误代码 pthread_mutex_destroy(&mutex);
pthread_mutex_destroy(shared_mutex);
  1. 可选:增加scanf返回值判断,避免读取失败时写入垃圾值:
for (int i = 0; i < n; ++i) {
    if (scanf("%d", &value) != 1) {
        perror("read input failed");
        break;
    }
    fprintf(file, "%d ", value);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 14:45:03