我为Linux编写了一个C实用程序,每秒检查一次/ proc / net / dev的内容。我使用fopen(“/ proc / net / dev”,“r”)打开文件,然后在完成后使用fclose()。
由于我使用的是'伪'文件而不是真实文件,每次我从中读取文件时是否打开/关闭文件都很重要,或者我应该在应用程序启动时打开它并保持打开状态整个时间?该实用程序作为守护进程启动,因此可能会运行很长时间。
答案 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”中的文件,则很容易从它们中获得意外结果。