как linux select () контролирует системный вызов двух файлов (файловых дескрипторов) и как использовать аргумент таймера - PullRequest
0 голосов
/ 08 января 2020

Мне нужно использовать системный вызов select, где мне нужно открыть два файла (файловые дескрипторы) и выполнить операцию чтения тех файлов, которые готовы, мне нужно использовать некоторое время ожидания через каждые 5 мс и читать из этих файлов. мой пример кода:

int main()
{

    fd_set readfds,writefds;
    ssize_t nbytes,bytes_read;
    char buf[20];
    int fd_1,fd_2,retval;
    struct timeval tv;

    fd_1 = open("test1.txt", O_RDWR);
    if(fd_1 < 0) {
        printf("Cannot open file...\n");
        return 0;
    }

    fd_2 = open("test2.txt", O_RDWR);
    if(fd_2 < 0) {
        printf("Cannot open file_2...\n");
        return 0;
    }

    /* Wait up to five seconds. */
    tv.tv_sec = 5;
    tv.tv_usec = 0;

    for(;;)
    {
        retval = select(FD_SETSIZE, &readfds, &writefds, NULL, &tv);
        printf("select");
        perror("select");
        exit(EXIT_FAILURE);

        //}
        for(int i=0; i < FD_SETSIZE; i++)
        {
            FD_ZERO(&readfds);
            if (FD_ISSET(i, &readfds))
            {
                // read call happens here //
                nbytes = sizeof(buf);
                bytes_read = read(i, buf, nbytes);
                printf("%ld", bytes_read);
            }
            else
            {
                perror("read");
                exit(EXIT_FAILURE);
            }
        }
    }

1 Ответ

0 голосов
/ 08 января 2020

Вам нужно инициализировать наборы файловых дескрипторов перед вызовом select(). С вашим текущим кодом select заканчивается EBADF.

Что-то вроде этого должно сделать это:

FD_ZERO (&writefds);

for(;;)
{
    FD_ZERO (&readfds);
    FD_SET(fd_1, &readfds);
    FD_SET(fd_2, &readfds);

    retval = select(FD_SETSIZE, &readfds, &writefds, NULL, &tv);
    if (retval < 0) {
        perror("select");
        exit(EXIT_FAILURE);
    }

    for(int i=0; i<FD_SETSIZE; i++)
    {
        if (FD_ISSET(i, &readfds))
        {
            // read call happens here //
            printf("reading from file: %d\n", i);

            nbytes = sizeof(buf);
            bytes_read = read(i, buf, nbytes);
            printf("read %ld bytes\n", bytes_read);
        }
    }
}

А также вы можете проверить, что for(;;) l oop и выход только по ошибке. Как только ваш select будет вести себя правильно, вы можете приступить к отладке внутри вашего второго for l oop. Кажется, вы не используете writefds здесь, поэтому вы также можете просто установить его на NULL в select.

Еще одно замечание: поскольку у вас есть только два файла в наборе для чтения, вы можете просто отметьте FD_ISSET(fd_1) / FD_ISSET(fd_2) вместо перебора всех записей FD_SETSIZE.

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