Valgrind提示程序退出时FIFO文件描述符未关闭问题排查求助
问题根因
你的文件描述符泄漏完全来自fifomanager_read函数的重复打开逻辑:
- 函数入口处你已经调用
fopen(FIFO_NAME, "r")打开了一次FIFO,拿到了初始的fp指针 - 进入do-while循环后第一行立刻又执行了一次
fopen(FIFO_NAME, "r"),直接把原来的fp指针覆盖,上一次打开的文件描述符没有被关闭,直接泄漏 - 每执行一次循环就会重复打开一次FIFO,循环多少次就会泄漏多少个文件描述符,Valgrind报的多个未关闭的MYFIFO就是这个原因
- 此外如果
fgets返回NULL,你没有关闭当前fp就进入下一轮循环,也会造成泄漏
修复方案
你不需要每次读FIFO都重新打开,保持一次打开循环读取即可,修正后的fifomanager_read参考代码:
void fifomanager_read() { int sequencenumber = 1; char recv_buf[MAX]; FILE*fp; // 只打开一次FIFO,不要重复打开 fp = fopen(FIFO_NAME, "r"); CHECK_FIFOOPEN(fp); FILE*logfile; logfile = fopen(FIFO_LOG, "a"); CHECK_FIFOOPEN(logfile); fprintf(logfile, "start of new log\n"); do { // 删掉循环里的重复fopen逻辑 if ( fgets(recv_buf, MAX, fp) != NULL ) { #ifdef DEBUG printf("Message received: %s", recv_buf); #endif //print to log file fprintf(logfile,"%d %ld %s",sequencenumber, time(NULL), recv_buf); sequencenumber++; } } while(strcmp(recv_buf, "End of logging process\n")!=0); int result = fclose( logfile ); CHECK_FIFOCLOSED(result); result = fclose( fp ); CHECK_FIFOCLOSED(result); #ifdef DEBUG printf("both files closed \n"); #endif }
其他优化建议
- 你当前
fifomanager_write的锁顺序有问题:先打开FIFO再加锁,打开FIFO的操作本身没有互斥保护,建议调整为先加锁再打开FIFO,避免并发写时的打开冲突 - 可以增加
recv_buf的合法性校验,避免传入空指针造成崩溃
内容的提问来源于stack exchange,提问作者Rik Van de Velde
相关产品推荐
相关产品推荐

