/proc伪文件的打开/关闭策略
我已经为Linux编写了一个C实用程序,它每秒检查一次/proc/net/dev的内容。我使用fopen(“/proc/net/dev”,“r”)打开文件,完成后使用fclose()/proc伪文件的打开/关闭策略,c,linux,file-io,C,Linux,File Io,我已经为Linux编写了一个C实用程序,它每秒检查一次/proc/net/dev的内容。我使用fopen(“/proc/net/dev”,“r”)打开文件,完成后使用fclose() 由于我使用的是一个“伪”文件,而不是一个真实的文件,那么我是否应该在每次读取文件时打开/关闭该文件,还是应该在我的应用程序启动时打开它并一直保持打开状态?该实用程序是作为守护进程启动的,因此可能会运行很长时间。这不要紧,不要紧。但是,缓存/缓冲可能会出现问题,这意味着最好(最安全)按照您的方式执行,并每次重新打开该
由于我使用的是一个“伪”文件,而不是一个真实的文件,那么我是否应该在每次读取文件时打开/关闭该文件,还是应该在我的应用程序启动时打开它并一直保持打开状态?该实用程序是作为守护进程启动的,因此可能会运行很长时间。这不要紧,不要紧。但是,缓存/缓冲可能会出现问题,这意味着最好(最安全)按照您的方式执行,并每次重新打开该文件。由于您很少这样做,因此不这样做不会获得性能,因此我建议保留您当前的解决方案。您需要的是无缓冲的阅读。假设不能切换到read()调用,请打开设备,然后将流设置为无缓冲模式。这还有一个额外的优点,即完成后无需关闭流。把它倒回去,再开始读
FILE *f = fopen("/proc/net/dev", "r");
setvbuf(f, NULL, _IONBF, 0);
while (running)
{
rewind(f);
...do your reading...
}
“/proc”中的伪文件对守护进程来说是危险的,因为如果内核决定删除它们,它们就会消失,留下一个无效的文件*
结构。这意味着您的策略是处理“/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);
}
}
}
因此,您可以看到,如果在程序运行期间内核删除了“/proc”中的文件,则很容易从这些文件中得到意外结果。您会遇到分段错误,因为您没有检查
fopen()
的返回,我认为不需要setvbuf()
。/proc
中的文件可以通过stdio缓冲读取。无论如何,我必须检查rewind()
是否丢弃了以前读取的数据,这在我的系统中就是如此。如果不确定,可以在倒带()之后使用fflush()
@YannDroneaud:观察得很好。9年:|
f5:~/tmp # ./a.out
Read: 255
Read: 0