C语言子进程日志重复问题求助及原实现失效原因咨询
问题分析:C语言子进程日志重复条目原因
核心原因拆解
1. 重复创建子进程导致的管道资源残留/继承问题
每次调用create_log_process()都会执行fork创建新子进程并建立管道,若end_log_process()未彻底清理资源:
- 若未调用
waitpid等待日志子进程完全退出,子进程会变成僵尸进程,其持有的管道文件描述符未被系统回收; - 父进程后续调用
create_log_process()时,新fork的子进程会继承这些残留的文件描述符,导致同一条日志消息被多个残留子进程接收并写入文件,形成重复条目。
2. fork后文件描述符的复制问题
父进程在open_db中创建日志子进程后,未完全关闭管道的所有冗余句柄就进入insert_sensor函数,再次执行create_log_process()时:
- 新子进程会继承父进程当前所有打开的文件描述符,包括前一次创建的日志管道读/写端;
- 若前一个日志子进程仍在运行(未被正确等待退出),新旧两个子进程会同时监听管道,同一条日志会被两次写入文件。
3. 日志子进程退出逻辑不严谨
如果end_log_process()仅关闭父进程侧的管道句柄,未确保子进程读完管道数据并退出:
- 管道内残留的日志数据会被后续启动的新日志子进程读取并写入;
- 父进程重复写入的日志消息,会被多个未彻底退出的子进程重复处理。
关于gdb调试的补充说明
设置follow-fork-mode child后无法进入子进程,大概率是因为子进程启动后很快执行完退出逻辑,gdb来不及跟进。可以尝试:
- 在
logger.c的子进程入口代码开头添加sleep(5),给gdb留足attach时间; - 使用
set detach-on-fork off配置,同时调试父子进程,避免丢失子进程的调试上下文。
内容的提问来源于stack exchange,提问作者dsdfs
相关产品推荐
相关产品推荐

