Функция Select (Linux) всегда возвращает 0

Функция выбора в моем случае всегда возвращает ноль, что является тайм-аутом, и это происходит постоянно, поэтому использование моего ЦП также достигает 98% для моего процесса. Я также пытался установить NULL вместо установки некоторого значения тайм-аута, но он все равно возвращает ноль. Я также использовал функцию опроса, заменяющую select. Та же проблема возникла и с опросом.

вот часть моего кода;

while(1)
{        
    value = 0;
    selectTimeOut = 0;
    memset(buf,0,SIZE);
    FD_ZERO(&read_fds);
    FD_SET(fd, &read_fds);
    struct timeval tv;
    tv.tv_sec = 10;
    tv.tv_usec = 1000;
    fdmax = fd;

    //using select to reduce cpu utilization
    selectret = select(fdmax + 1,&read_fds,NULL,NULL,&tv);
    if (selectret == -1)
    {
       print_sync("/home/fes/syclogs.txt","Select fails");
       exit(0);
    }
    else
    {
        print_sync("/home/fes/syclogs.txt","Error set is %s",strerror(errno));
        if(!FD_ISSET(fd, &read_fds))
        {
            print_sync("/home/fes/syclogs.txt","Select Time Out");
            selectTimeOut = 1;
        }
    }
    if(selectTimeOut == 1)
        continue;
    noread  = read(fd,buf,SIZE);
}

person Sandeep Singh Phogat    schedule 18.05.2011    source источник
comment
а где код функции select() ??   -  person Sriram    schedule 18.05.2011
comment
select — это системный вызов в системах UNIX.   -  person Kiril Kirov    schedule 18.05.2011
comment
как вы получаете fd? вы уверены, что это действительно?   -  person Mat    schedule 18.05.2011
comment
Я считаю, что select вернет -1, если будет вызван с недопустимым fd. В таких случаях я обычно использую strace, чтобы увидеть, что происходит на самом деле.   -  person Code Painters    schedule 18.05.2011
comment
Почему вы выходите с 0 при ошибке?   -  person Ignacio Vazquez-Abrams    schedule 18.05.2011
comment
Изучение errno, когда select не вернуло -1, бессмысленно и фальшиво.   -  person R.. GitHub STOP HELPING ICE    schedule 18.05.2011
comment
Кроме того, заголовок вашего вопроса и код не совпадают. Нигде вы не проверяете, равно ли значение, возвращаемое select, 0. Вероятно, оно равно 1, и в этом случае это означает, что есть данные для чтения.   -  person R.. GitHub STOP HELPING ICE    schedule 18.05.2011
comment
да, обряд, но я проверял errno в select, возвращающем нулевое условие, когда я перепробовал все варианты .... теперь здесь fd - это именованный канал fd ... я использовал вызов mkfifo ... и открыл канал, используя open in read только режим ..... и из журналов я проверил, что fd является положительным нет .. я имею в виду действительный fd .....   -  person Sandeep Singh Phogat    schedule 20.05.2011


Ответы (2)


Ваша логика не имеет смысла. errno интересен только в том случае, если select() возвращает -1. Если он возвращает ноль, значит, ни один fd не был готов, значит, был тайм-аут, и больше ничего тестировать не нужно. Если он возвращает положительное значение, вам нужно зациклить и обработать столько готовых fd.

person user207421    schedule 19.05.2011

Почему бы вам не проверить конец файла или подобное условие? Я считаю, что EOF или другое исключительное состояние вашего дескриптора идеально подходит для этой ситуации.

Вероятно, вам следует дополнительно описать дескриптор и контекст. Откуда фд? Какой источник данных он представляет?

Глядя на ваши отладочные сообщения, можно прийти к выводу, что вы пытаетесь отслеживать изменения в обычном файле. Я не думаю, что select может помочь с этой задачей.

Исходный код утилиты Tail может помочь вам реализовать ваш код мониторинга файлов.

person Basilevs    schedule 18.05.2011
comment
Он проверяет конец файла «или подобное условие», а не наличие подобных условий. Если есть EOS, ожидающий чтения, fd будет присутствовать в наборе read_fds, поэтому он не увидит тайм-аут select и упадет до своего вызова read(), где он сможет его обнаружить (noread == 0). - person user207421; 19.05.2011
comment
Ну, я просто не могу представить таймаут выбора в обычном файле. - person Basilevs; 19.05.2011
comment
Не говоря уже об ожидании. - person Basilevs; 19.05.2011
comment
Я не знаю, о чем все это. Ничего из этого не имеет смысла. Вы спрашиваете, почему он не проверяет EOS, если он не опубликовал эту часть кода. Это почти наверняка не «обычный файл», а сокет: сокеты также имеют условие EOS и условия, при которых select() может истечь. Похоже, вы даже не знаете, что такое select(). - person user207421; 20.05.2011
comment
теперь здесь fd - это именованный канал fd ... я использовал вызов mkfifo ... и открыл канал, используя open только в режиме чтения ... и из журналов, которые я проверил, fd является положительным нет ... я имею в виду действительный fd ..... - person Sandeep Singh Phogat; 20.05.2011
comment
@EJP, /home/fes/syclogs.txt мне показалось довольно обычным именем. @user758885 user758885 отправляет конец, подключенный к этому каналу? Положительность fd просто означает успешное открытие, состояние канала должно быть проверено другими способами. - person Basilevs; 21.05.2011
comment
@user758885 user758885, кстати, выбор прерывается сигналами, и BROKEN PIPE является одним из них. - person Basilevs; 21.05.2011
comment
@Basilevs: (a) это имя его файла журнала: нет никаких доказательств того, что это fd, который он выбирает; (b) он уже сказал нам, что выбирает именованный канал; (c) «положительность fd», если вы имеете в виду FD_ISSET, означает, что событие, для которого он выбирает, произошло; (d) состояние канала можно определить с помощью select(): для этого он и предназначен. Вы продолжаете не иметь смысла. - person user207421; 21.05.2011
comment
@EJP: а) Это может быть что угодно. б) Только в моем втором комментарии. в) Нет, я имею в виду положительность значения, возвращаемого open() - то, о чем говорит ОП в своем предыдущем комментарии. г) Состояние абстрактного файлового дескриптора может быть любым, как вы можете описать его с помощью такой узкий интерфейс? Я предпочитаю думать, что select обрабатывает события, а не состояния. - person Basilevs; 21.05.2011
comment
хорошо, ребята, у меня есть решение .... на самом деле я открывал канал в режиме RDONLY раньше.. теперь изменил его на режим RDWR .... потому что откуда-то я узнал, что канал открыт в режиме RDONLY ... всегда будет возвращаться вызов чтения выполнен успешно, но возвращается значение = 0, чтобы избавиться от этого, вам нужно изменить его на режим RDWR ..... - person Sandeep Singh Phogat; 22.05.2011
comment
@Basilevs (а) точно, так что ваше замечание об «обычном имени» ничего не значит; (b) не было никаких предварительных доказательств, которые он выбирал в деле; действительно, наличие имени файла в сочетании с функцией select(), которая работает с fd, указывает на то, что он не выбирал этот файл; (c) и (d) допустимо положительное fd, опять же я понятия не имею, о чем идет речь; (e) договориться о доставке событий select(), и (f) EOS не заставляет select() возвращать ноль. - person user207421; 23.05.2011