【问题标题】:Open/close strategy for /proc pseudo-file/proc 伪文件的打开/关闭策略
【发布时间】:2009-10-26 08:52:43
【问题描述】:

我为 Linux 编写了一个 C 实用程序,它每秒检查一次 /proc/net/dev 的内容。我使用 fopen("/proc/net/dev", "r") 打开文件,然后在完成后使用 fclose()。

由于我使用的是“伪”文件而不是真实文件,所以每次读取文件时打开/关闭文件是否重要,还是应该在应用程序启动时打开它并保持打开状态整个时间?该实用程序作为守护进程启动,因此可能会运行很长时间。

【问题讨论】:

    标签: c linux file-io


    【解决方案1】:

    没关系,不。但是,缓存/缓冲可能存在问题,这意味着实际上最好(最安全)按照您的方式进行操作,并且每次都重新打开文件。由于您很少这样做,因此不这样做不会获得任何性能,因此我建议您保留当前的解决方案。

    【讨论】:

      【解决方案2】:

      你想要的是无缓冲的阅读。假设您不能只切换到 read() 调用,打开设备,然后将流设置为无缓冲模式。这还有一个额外的好处,即完成后无需关闭流。只需倒带,重新开始阅读。

      FILE *f = fopen("/proc/net/dev", "r");
      setvbuf(f, NULL, _IONBF, 0);
      while (running)
      {
          rewind(f);
          ...do your reading...
      }
      

      【讨论】:

      • 我不认为setvbuf() 是必需的。 /proc 中的文件可以通过 stdio 缓冲读取。无论如何,我必须检查rewind() 确实丢弃了以前读取的数据,我的系统就是这种情况。如果不确定,可以在rewind() 之后使用fflush()
      【解决方案3】:

      “/proc”中的伪文件对于守护进程来说是危险的,因为如果内核决定删除它们,它们就会消失,留下一个无效的FILE * 结构。这意味着您的策略是处理“/proc”中文件的唯一正确策略(但没有人会期望内核在运行时删除“/proc/net/dev”)。

      一般情况下(尤其是“/proc/[PID]”中的文件)应该在操作前打开“/proc”中的文件,并在操作完成后尽快关闭它们。

      请参阅此示例代码。它分叉并读取子进程的“/proc/[PID]/status”文件,一次在子进程退出之前,一次在子进程清理期间。

      #include <unistd.h>
      #include <time.h>
      #include <stdio.h>
      #include <sys/types.h>
      #include <sys/wait.h>
      
      int main(int argc, char** argv){
          pid_t child=fork();
      
          if(child==0){
              sleep(1);
          } else {
              char path[256],buffer[256]; int status,read_length;
              sprintf(path,"/proc/%i/status",child);
              //do a read while the child is alive
              FILE *fd=fopen(path,"r");
              if(fd!=0){
                  read_length=fread(buffer,1,255,fd);
                  printf("Read: %i\n",read_length);
                  fclose(fd);
              }
              //repeat it while the child is cleaned up
              fd=fopen(path,"r");
              wait(&status);
              if(fd!=0){
                  read_length=fread(buffer,128,1,fd);
                  printf("Read: %i\n",read_length);
                  fclose(fd);
              }
          }
      }
      

      结果如下

      f5:~/tmp # ./a.out 
      Read: 255
      Read: 0
      

      如您所见,如果“/proc”中的文件在您的程序运行时被内核删除,您很容易得到意外结果。

      【讨论】:

      • 你得到一个分段错误,因为你没有检查fopen()的返回
      猜你喜欢
      • 1970-01-01
      • 2017-05-26
      • 1970-01-01
      • 2011-11-26
      • 2012-10-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-11
      • 1970-01-01
      相关资源
      最近更新 更多