Стратегия открытия / закрытия псевдо-файла / proc - PullRequest
5 голосов
/ 26 октября 2009

Я написал утилиту C для Linux, которая каждую секунду проверяет содержимое / proc / net / dev. Я открываю файл, используя fopen ("/ proc / net / dev", "r") и затем fclose (), когда я закончу.

Поскольку я использую псевдо-файл, а не настоящий, имеет ли значение, открываю ли я / закрываю ли файл каждый раз, когда читаю его, или мне просто нужно открыть его при запуске приложения и оставить его открытым Все время? Утилита запускается как процесс-демон и может работать долго.

Ответы [ 3 ]

3 голосов
/ 26 октября 2009

Это не должно иметь значения, нет. Однако могут быть проблемы с кэшированием / буферизацией, что означает, что на самом деле лучше (безопаснее всего) делать так, как вы делаете, и каждый раз заново открывать файл. Так как вы делаете это так редко, вы не сможете повысить производительность, поэтому я бы порекомендовал сохранить ваше текущее решение.

2 голосов
/ 26 октября 2009

То, что вы хотите, это небуферизованное чтение. Предполагая, что вы не можете просто переключиться на вызов read (), откройте устройство и затем установите поток в небуферизованный режим. Это дает дополнительное преимущество: нет необходимости закрывать поток, когда вы закончите. Просто перемотайте его и начните читать снова.

FILE *f = fopen("/proc/net/dev", "r");
setvbuf(f, NULL, _IONBF, 0);
while (running)
{
    rewind(f);
    ...do your reading...
}
0 голосов
/ 17 июля 2018

Псевдофайлы в "/ 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", если они будут удалены ядром во время выполнения вашей программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...