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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 06:48:01