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

基于Semaphore的文件搜索程序fprintf写日志为空问题求助

问题根因排查

导致日志文件空白的核心原因是stdio缓冲区未正确刷新到磁盘,具体问题点如下:

  • 程序中所有进程退出均调用了_exit()系统调用:该调用会直接终止进程进入内核,不会刷新C标准库的用户态I/O缓冲区,所有通过fprintf写入的内容全部停留在内存中,没有落盘。
  • 仅给stdout设置了行缓冲,未给日志文件指针fptr设置缓冲模式:默认情况下文件流使用全缓冲策略,只有缓冲区写满、进程主动调用fflush/fclose时才会刷入磁盘,你的程序未触发上述条件。
  • main函数末尾的fclose(fptr)逻辑永远不会执行:父子进程均在各自的业务逻辑函数中提前退出,没有机会调用fclose触发缓冲区刷新。
  • 信号处理函数未注册:你定义了signalHandeler1、signalHandeler2两个信号处理函数,但未通过signal()系统调用绑定对应信号,进程收到信号后直接按默认逻辑终止,不会执行处理函数中的日志写入逻辑,也不会刷新缓冲区。
  • 输入环节的日志没有换行符:do-while循环中输入文件名的fprintf语句末尾没有加\n,即使配置行缓冲也不会触发自动刷盘。

修复方案

按以下步骤修改代码即可解决日志空白问题:

  1. 打开日志文件后立即为其设置行缓冲,保证每行日志写完自动刷盘
fptr = fopen("deadlockoutput.txt", "w+");
// 新增以下行
setvbuf(fptr, NULL, _IOLBF, 0);
  1. 将代码中所有_exit()调用替换为exit():exit()会自动刷新所有打开的文件缓冲区后再终止进程。
  2. 注册信号处理函数,在main函数初始化阶段增加以下代码:
signal(SIGTERM, signalHandeler1);
signal(SIGUSR2, signalHandeler2);
  1. 输入环节的日志增加换行符:
fprintf(fptr,"_Please input a real file:   %s_\n", file);
  1. (可选)如果极端场景下如果仍有日志丢失的话,可在每次fprintf后手动调用fflush(fptr)强制刷盘。

额外优化建议

  • 父子进程同时写日志会出现内容穿插问题,可配合信号量保证日志写入的原子性,避免两行日志内容混杂。
  • 日志内容建议增加时间戳、进程ID标识,方便区分不同进程的日志排查死锁相关信息,符合作业要求的进程活动记录规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:09:02