Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
/proc伪文件的打开/关闭策略_C_Linux_File Io - Fatal编程技术网

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

/proc伪文件的打开/关闭策略,c,linux,file-io,C,Linux,File Io,我已经为Linux编写了一个C实用程序,它每秒检查一次/proc/net/dev的内容。我使用fopen(“/proc/net/dev”,“r”)打开文件,完成后使用fclose() 由于我使用的是一个“伪”文件,而不是一个真实的文件,那么我是否应该在每次读取文件时打开/关闭该文件,还是应该在我的应用程序启动时打开它并一直保持打开状态?该实用程序是作为守护进程启动的,因此可能会运行很长时间。这不要紧,不要紧。但是,缓存/缓冲可能会出现问题,这意味着最好(最安全)按照您的方式执行,并每次重新打开该

我已经为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