/ proc伪文件的打开/关闭策略

时间:2009-10-26 08:52:44

标签: c linux file-io

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

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

3 个答案:

答案 0 :(得分:3)

没关系,不。但是,缓存/缓冲可能存在问题,这意味着它实际上最好(最安全),并且每次都重新打开文件。由于你这么做很少,所以没有这样做就没有表现,所以我建议保留你当前的解决方案。

答案 1 :(得分:2)

你想要的是无缓冲的阅读。假设您不能只切换到read()调用,请打开设备,然后将流设置为无缓冲模式。这具有额外的优点,即在完成后无需关闭流。只需回放它,然后重新开始阅读。

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

答案 2 :(得分:0)

“ / 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”中的文件,则很容易从它们中获得意外结果。