[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: oftopic: (2) select()& O_NONBLOCK



On Sat, Jun 02, 2001 at 06:35:42PM +0700, Pavel Orehov wrote:
> Прошу прощения за дикий офтопик, но сильно надо, а в книжках и мане вопрос
> совершенно не освещен и других _дружественных_ мест я не знаю...

comp.unix.programmer место весьма достойное.

> 
> вобщем писал модуль к ucd-snmnpd и обнаружил эфект:
> Надо прочитать из FIFO (устройства) ASCIIz строку.
> Поступаю просто (http://oniltz.da.ru/~opa/test.c)

Достучаться не могу, поэтому буду говорить про написанное.

> $mkfifo file
> ..
> fd=open(file,O_RDONLY);
> FD_SET(fd,&set);
> if(select(,&set,0,0,0)>0)
>   if(FD_ISSET(fd,&set))
>     read(fd,buf+ofs,1);

А кто результат read проверять будет? Да и чтение по байтику --
удовольствие дорогое. Очень.

      result = read (fd, buf+ofs, spaceleft);
      if (result == 0) { /* данные кончились, больше не будет */ }
      if (result < 0) { /* случилось страшное */ }
      ofs += result; spaceleft -= result;

И неблокирующее чтение в этом случае уже и не нужно.

>     if(buf[ofs]=='\n')printf("we got a line");
> ...
> 
> ладно... так все делают, но не охото на чтение _КАЖДОГО_БАЙТА_
> (напоминаю: строка ASCIIz) ходить до селекта (кто видел основной цикл
> ucd-snmpd согласится)
> 
> тут возникает вопрос: а сколько байтов есть в буфере? fstat.st_size==0
> 

Лишний это вопрос. Сколько есть - все твои. :)

> ладно пишу 
> fd=open(file,O_RDONLY|O_NONBLOCK);
> ...
>  for(;;){
>    n=read(fd,buf+ofs,1);
>    if(n<=0)return;

Это бесчеловечный поступок. Нельзя неблокирующим чтением в цикле без
остановки ...

Опять же, кто на EWOULDBLOCK проверять будет? Не все то ошибка, что -1 из
read.

>    if(buf[ofs]=='\n')printf("we got a line");
>    ofs++;
>  } 
> 
> и тут случается чудо: после получения первого байта у select начинается
> недержание: непрерывно срывается с моим fd, но read, разумеется,
> честно возвращает 0.

Если select сказал, что из fd читать можно, а read вернул 0, то это
однозначно кончились данные и в этом fd уже ничего интересного не будет.

> 
> Вопрос: как бороться с этой тварью, или
> 1. как узнать кол-во данных/места в буфере для чтения/записи

Не надо.

> 2. как ее успокоить

Аккуратно проверять, что вернул read.

> 3. что почитать на эту тему и окрестности кроме текстов ядра

Stevens. APUE. Полная библиографическая ссылка в разных FAQ. В FAQ из
comp.unix.programmer она точно есть.

> если сильно не хочется за каждым байтом ходить к селекту и еще сильнее не
> хочится переходить на бинарный формат с фиксированным размером блока.
> подпорки типа семафоров/msgq/сигналов еще больше не нравятся (это близко
> к вопросу о M$vsUNIX)
> 

Ужас какой. Не надо придумывать никаких сигналов. А уж тем более семафоров
и очередей, ибо на них тот же select не скажешь.

> 4. вообще какая книжка по программированию Unix хорошая?
> 

См. пункт 3.

> хоть какая отмазка: все это программируется под потатой и для работы на
> потате
> 
> 

:))

-- 
dg



Reply to: