select () не ждет - PullRequest
       3

select () не ждет

2 голосов
/ 04 сентября 2010

Мне нужно прочитать файл журнала программы и для этого я хотел использовать select () и read ()

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <fcntl.h>
#include <stdio.h>


int main()
{
    int fd = -1;
    fd_set fds;
    struct timeval tv;
    int rc; 
    char buffer[4096];
    char * log_path = "/home/mich/a.txt";
    if((fd = open(log_path,O_RDONLY) ) == -1 )
    {
        printf("error\n");
            return -1;
    }

    while(1)
    {

        FD_ZERO(&fds);
        FD_SET(fd,&fds); 
        tv.tv_sec = 2;
        tv.tv_usec = 0;
        rc = select(fd+1, &fds, NULL, NULL, &tv);

            if (rc < 0) {
                printf("failed\n");
                continue;
            } else if (rc > 0 && FD_ISSET(fd,&fds)) {
                printf("read\n");
            } else  {
                printf("timeout\n");
                continue;
            }
        while ((my_getline(buffer,sizeof(buffer),fd)) > 0)  
        {
            printf("%s",buffer);
        }   
    }
    close(fd);
}

my_getline - это функция, которая использует read ().

Выход:

read
aaa
read
read
read
read
read
bbb
read
read
read
read
...

где aaa и bbb - строки из прочитанного файла.

Что не так в этой программе?

Ответы [ 2 ]

4 голосов
/ 04 сентября 2010

select() говорит вам, что read() не будет блокироваться.

Это включает в себя случай, когда он вернет 0, чтобы указать конец файла, что, вероятно, является тем, что выполучение.

2 голосов
/ 04 сентября 2010

select говорит вам, что что-то ждет на fd.Это не обязательно должна быть строка, это может быть один байт или информация о том, что достигнут конец файла.Добавьте puts("####"); в конце внешнего цикла while, чтобы увидеть, как ваш код обрабатывает входной файл.

Чтобы узнать, как продолжить чтение файла, к которому добавляются другие процессы, посмотрите исходный коддля одной из бесплатных реализаций утилиты unix tail (в частности, ее опция -f).Традиционная реализация состоит в том, чтобы прочитать весь файл, поспать в течение небольшого интервала (1 секунда в tail) и повторить с позиции, в которой вы остановились после последнего чтения.Более современный, более оперативный, менее ресурсоемкий, но менее переносимый подход использует API уведомления об изменении файла (inotify в Linux, kqueue в * BSD, ...).

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