Russian Qt Forum
Ноябрь 01, 2024, 09:39 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: read() Выход из чтения по таймеру  (Прочитано 13541 раз)
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« : Январь 27, 2015, 08:24 »

Есть обмен между двумя процессами через pipe fifo.
Код:
int fifo_out = open (pathname, O_RDONLY);
int bytes = read(fifo_out, (void *)&info_data, sizeof(InfoData));

как выйти из read, если в течении 70 мс в pipe не поступили данные?
Записан
Fat-Zer
Гость
« Ответ #1 : Январь 27, 2015, 08:58 »

используй poll(2) или select(2) и читай только когда данные появятся...

Другие варианты решения:
 - можно открывать c [или ставить позже] O_NONBLOCK. далее фантазировать около sleep'ов и ручного управления таймерами
 - [относительно извращённый] можно подписаться на SIGALRM с помощью alarm(2) или более новых интерфейсов. и плясать от этого. read() должен будет возвращаться c EINTR.
« Последнее редактирование: Январь 27, 2015, 09:06 от Fat-Zer » Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #2 : Январь 27, 2015, 09:50 »

используй poll(2) или select(2) и читай только когда данные появятся...

вроде то что нужно.... но при обмене через fifo pipe может быть такое что жду пулом или селектом данных. должно прийти 10 байт. я вышел из селекта по событию "есть данные для чтения". Начинаю ридом читать, а там данные не все, только 8 байт, остальные не пришли (такое бывает при обмене через UART). Отправитель всегда шлёт по 10 байт. гарантированно. Нужно мне, при такой организации обмена проверять, что если после селекта рид вычитал 8 байт, то ещё раз зайти в селект и попытаться дополучить 2 байта, если не пришли, то бракую пакет?
Записан
Fat-Zer
Гость
« Ответ #3 : Январь 27, 2015, 10:12 »

вроде то что нужно.... но при обмене через fifo pipe может быть такое что жду пулом или селектом данных. должно прийти 10 байт. я вышел из селекта по событию "есть данные для чтения". Начинаю ридом читать, а там данные не все, только 8 байт, остальные не пришли (такое бывает при обмене через UART). Отправитель всегда шлёт по 10 байт. гарантированно. Нужно мне, при такой организации обмена проверять, что если после селекта рид вычитал 8 байт, то ещё раз зайти в селект и попытаться дополучить 2 байта, если не пришли, то бракую пакет?
да, всё так.
FYI: но если нужно жёстко следить, чтобы при повторном select'е у него был только остаток времени, то придётся делать это ручками... полагаться на то что select изменит таймер не стоит.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #4 : Январь 27, 2015, 10:14 »

FYI: но если нужно жёстко следить, чтобы при повторном select'е у него был только остаток времени, то придётся делать это ручками... полагаться на то что select изменит таймер не стоит.
Такое проще делать отдельным таймером.
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #5 : Январь 27, 2015, 10:16 »

да, всё так.
FYI: но если нужно жёстко следить, чтобы при повторном select'е у него был только остаток времени, то придётся делать это ручками... полагаться на то что select изменит таймер не стоит.
плохо. лучше наверно таймер задавать на ожидание 1 байта и принимать по 1 байту
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #6 : Январь 27, 2015, 10:28 »

плохо. лучше наверно таймер задавать на ожидание 1 байта и принимать по 1 байту
Зачем? Вы установили таймер на 70 мс и запустили цикл пулинга. Данные могут прийти несколькими кусками. Если успели все принять, до срабатывания таймера - все ок, таймер сработал раньше - не ок.
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #7 : Январь 27, 2015, 11:30 »

плохо. лучше наверно таймер задавать на ожидание 1 байта и принимать по 1 байту
Зачем? Вы установили таймер на 70 мс и запустили цикл пулинга. Данные могут прийти несколькими кусками. Если успели все принять, до срабатывания таймера - все ок, таймер сработал раньше - не ок.

ээээ.... не понял. на русском языке не понятно, можете на с++ тоже самое сказать?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #8 : Январь 27, 2015, 11:42 »

ээээ.... не понял. на русском языке не понятно, можете на с++ тоже самое сказать?
На чем вам будет удобней: на Qt или boost?
Или рекомендую для организации пулинга использовать libev. Там тоже есть таймеры.
« Последнее редактирование: Январь 27, 2015, 11:47 от Old » Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #9 : Январь 27, 2015, 12:11 »

да хоть на чем. и причем здесть буст или кьют? вы предлагаете внешний таймер использовать? костыльный вариант по мойму. Покажите как это будет с внешним таймером выглядеть?
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Январь 27, 2015, 12:25 »

и причем здесть буст или кьют?
В них уже есть пулинг и таймеры. Как я уже написал выше, есть еще несколько удобных и быстрых библиотек для этого.
Но это несложно и завелосипетить самому, конечно если есть свободное время.

вы предлагаете внешний таймер использовать? костыльный вариант по мойму.
Что значит внешний таймер?
Кто-то должен засекать время, таймер для этого подходит лучше всего.

Покажите как это будет с внешним таймером выглядеть?

Да все элементарно.

Код
C++ (Qt)
// Запускается таймер на необходимый интервал, когда он срабатывает, вызывается функция onTimeout
// Запускается пулинг, при появлении данных для чтения, вызывается функция onReadyRead
 
void onTimeout()
{
   // Здесь мы знаем, что время вышло, а данные не пришли
}
 
void onReadyRead()
{
   // Доступны не все данные, выходим и ждем еще
   // (или вычитываем все доступные во внутренний буфер)
   if( bytesAvailable() < 10 )
       return;
 
   // Все данные доступны - останавливаем таймер
   timer->stop();
 
   // Вычитываем и/или обрабатываем данные
}
 
Записан
qate
Супер
******
Offline Offline

Сообщений: 1176


Просмотр профиля
« Ответ #11 : Январь 27, 2015, 12:36 »

если именно обмен с uart, то почему не через QSerialPort ?
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


Просмотр профиля
« Ответ #12 : Январь 27, 2015, 12:38 »

если именно обмен с uart, то почему не через QSerialPort ?

обмен c другой программой через fifo pipe
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #13 : Январь 27, 2015, 12:48 »

если именно обмен с uart, то почему не через QSerialPort ?
В линуксе практически для любого хендла можно использовать QSocketNotifier, с пайпами в том числе.
Записан
qate
Супер
******
Offline Offline

Сообщений: 1176


Просмотр профиля
« Ответ #14 : Январь 27, 2015, 13:01 »

тогда наверно неблокирующий read поможет
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.078 секунд. Запросов: 22.