基于Semaphore的文件搜索程序fprintf写日志为空问题求助
问题根因排查
导致日志文件空白的核心原因是stdio缓冲区未正确刷新到磁盘,具体问题点如下:
- 程序中所有进程退出均调用了
_exit()系统调用:该调用会直接终止进程进入内核,不会刷新C标准库的用户态I/O缓冲区,所有通过fprintf写入的内容全部停留在内存中,没有落盘。 - 仅给stdout设置了行缓冲,未给日志文件指针
fptr设置缓冲模式:默认情况下文件流使用全缓冲策略,只有缓冲区写满、进程主动调用fflush/fclose时才会刷入磁盘,你的程序未触发上述条件。 main函数末尾的fclose(fptr)逻辑永远不会执行:父子进程均在各自的业务逻辑函数中提前退出,没有机会调用fclose触发缓冲区刷新。- 信号处理函数未注册:你定义了
signalHandeler1、signalHandeler2两个信号处理函数,但未通过signal()系统调用绑定对应信号,进程收到信号后直接按默认逻辑终止,不会执行处理函数中的日志写入逻辑,也不会刷新缓冲区。 - 输入环节的日志没有换行符:
do-while循环中输入文件名的fprintf语句末尾没有加\n,即使配置行缓冲也不会触发自动刷盘。
修复方案
按以下步骤修改代码即可解决日志空白问题:
- 打开日志文件后立即为其设置行缓冲,保证每行日志写完自动刷盘
fptr = fopen("deadlockoutput.txt", "w+"); // 新增以下行 setvbuf(fptr, NULL, _IOLBF, 0);
- 将代码中所有
_exit()调用替换为exit():exit()会自动刷新所有打开的文件缓冲区后再终止进程。 - 注册信号处理函数,在
main函数初始化阶段增加以下代码:
signal(SIGTERM, signalHandeler1); signal(SIGUSR2, signalHandeler2);
- 输入环节的日志增加换行符:
fprintf(fptr,"_Please input a real file: %s_\n", file);
- (可选)如果极端场景下如果仍有日志丢失的话,可在每次
fprintf后手动调用fflush(fptr)强制刷盘。
额外优化建议
- 父子进程同时写日志会出现内容穿插问题,可配合信号量保证日志写入的原子性,避免两行日志内容混杂。
- 日志内容建议增加时间戳、进程ID标识,方便区分不同进程的日志排查死锁相关信息,符合作业要求的进程活动记录规范。
内容的提问来源于stack exchange,提问作者zhaoyun255
相关产品推荐
相关产品推荐

