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

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

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

Сообщений: 570


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

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

Цитировать
// Доступны не все данные, выходим и ждем еще
а сколько ждать?
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


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

тогда наверно неблокирующий read поможет
так наоборот нужно заблокировать до прихода пакета или до таймаута.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

Это значит то, то например при чтении из уарта ни каких специальных таймеров не создается. после настройки таймаутов read блокирует выполнение потока на ожидании всех байт, либо до тайм аута. В прицепе тоже самое ожидание можно организовать селектом и пулом без всяких внешних таймеров.
Да ради Бога, таймер это удобная сущность для учета времени и не более.
Вы можете просто сохранять текущее время до начала ожидания данных и сравнивает его с текущем при каждом срабатывании того же селекта.

а сколько ждать?
Следующего цикла пулинга.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

так наоборот нужно заблокировать до прихода пакета или до таймаута.
Блокировать не обязательно, главное дождаться или одного или другого события.
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


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

так наоборот нужно заблокировать до прихода пакета или до таймаута.
Блокировать не обязательно, главное дождаться или одного или другого события.

нужно блокировать. в этом фишка. иначе можно просто

while( (timerIsOut() == false) || ( bytesAvailable() < 10 ) ); лишняя нагрузка.

Цитировать
Следующего цикла пулинга.
что получается в вашем алгоритме: запустили таймер на 70 мс. запустили пулинг на 70мс. ждём.... через 50 мс получили кусок пакета... проверяем bytesAvailable() < 10 и запускаем следующий цикл пулинга... т.е. на 70 мс. больше байт допустим нет в пайпе. пулинг ждёт свои 70 мс. срабатывает таймер и вызывает onTimeout(). ...... вот тут как-то не всё элементарно.... что дальше? как onTimeout прервёт пулинг, которому ещё ждать 50 мс?
Записан
qate
Супер
******
Offline Offline

Сообщений: 1177


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


нужно блокировать. в этом фишка. иначе можно просто

while( (timerIsOut() == false) || ( bytesAvailable() < 10 ) ); лишняя нагрузка.


while( (timerIsOut() == false) || ( bytesAvailable() < 10 ) ) usleep(10000); // 10 мсек поспать всегда можно - нет тут нагрузки
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

нужно блокировать. в этом фишка. иначе можно просто

while( (timerIsOut() == false) || ( bytesAvailable() < 10 ) ); лишняя нагрузка.
Так пулинг и создан, что бы избавить нас от таких проверок и ненужных нагрузок.
Если данных для чтения не будет, то мы ничего делать и не будем.

что получается в вашем алгоритме: запустили таймер на 70 мс. запустили пулинг на 70мс. ждём.... через 50 мс получили кусок пакета... проверяем bytesAvailable() < 10 и запускаем следующий цикл пулинга... т.е. на 70 мс. больше байт допустим нет в пайпе. пулинг ждёт свои 70 мс. срабатывает таймер и вызывает onTimeout(). ...... вот тут как-то не всё элементарно.... что дальше? как onTimeout прервёт пулинг, которому ещё ждать 50 мс?
Как правило программа должна делать много разных вещей, по мимо сидения в select. Поэтому селект запускают с нулевым таймаутом (или очень маленьким), тогда он не ждет, а выходит сразу. Мы смотрим, есть что прочесть - читаем, потом мы делаем свои дела, например, смотрим на время (таймеры) и уходим в начало цикла на селект. И т.д.
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


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


нужно блокировать. в этом фишка. иначе можно просто

while( (timerIsOut() == false) || ( bytesAvailable() < 10 ) ); лишняя нагрузка.


while( (timerIsOut() == false) || ( bytesAvailable() < 10 ) ) usleep(10000); // 10 мсек поспать всегда можно - нет тут нагрузки
не всегда можно. мне нужно ждать запрос. если запроса нет в течении 70 мс, то план Б.
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


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

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


Цитировать
Как правило программа должна делать много разных вещей, по мимо сидения в select. Поэтому селект запускают с нулевым таймаутом (или очень маленьким), тогда он не ждет, а выходит сразу. Мы смотрим, есть что прочесть - читаем, потом мы делаем свои дела, например, смотрим на время (таймеры) и уходим в начало цикла на селект. И т.д.
Дак это вообще не то что мне нужно. То что вы предлагаете, чтобы селект не ждал а сразу выходил, можно сделать, как вы говорите элементарно, без всяких селектов

Код:
while( (timerIsOut() == false) || ( bytesAvailable() < 10 ) ); 

Мне же надо заблокироваться в ожидании до приема 10 байт, и прервать ожидание по таймауту, как это делается на примере read() с уртом.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

Мне же надо заблокироваться в ожидании до приема 10 байт, и прервать ожидание по таймауту, как это делается на примере read() с уртом.
Я не могу понять для чего вы хотите именно заблокироваться в read?
Если можно не блокироваться и вычитывать по частям ваши 10 байт + контролировать время, для определения таймаута?
Вам шашечки или ехать?
И последовательный порт, и пайпы, и сокеты (локальные/сетевые) можно читать не блокируя, сколько нужно с контролем времени.
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


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

Я не могу понять для чего вы хотите именно заблокироваться в read?
так вот с этого бы и начали, а потом бы уже предлагали неблокирующее чтение. Для чего мне нужно блокировать - это уже выходит за рамки этого топика.
Цитировать
Вам шашечки или ехать?
я сразу сказал, что мне нужно читать блокируя с контролем времени.
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



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

Я не могу понять для чего вы хотите именно заблокироваться в read?
...
И последовательный порт, и пайпы, и сокеты (локальные/сетевые) можно читать не блокируя, сколько нужно с контролем времени.
Предположу, что если речь идет о Windows и о пайпе, связанном с перенаправленным stdin, - будут проблемы с неблокируемым чтением. На эту тему тут на форуме несколько постов было.
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



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

я сразу сказал, что мне нужно читать блокируя с контролем времени.
Вижу два варианта - пользоваться системным API для имитации синхронного чтения через (Windows) ReadFile с Overlapped и WaitForSingleObject с 70 мс или читать в отдельном потоке, а по истечению 70 мс снаружи закрывать дескриптор читаемого файла - тогда "зависший" read вывалится с ошибкой.
Второй вариант выглядит значительно более корявым, но работает для того же чтения из stdin. Первый - по сути способ реализации того, что уже предлагал тут Old, но он Вам не нравится...
Записан
juvf
Программист
*****
Offline Offline

Сообщений: 570


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

Предположу, что если речь идет о Windows и о пайпе, связанном с перенаправленным stdin, - будут проблемы с неблокируемым чтением. На эту тему тут на форуме несколько постов было.
сорри , сразу не сказал что речь про линукс. Но как увидел poll И select - сразу в маны. Это же библиотечные вызовы UNIX. Разве они в винде есть?


ps
Цитировать
по сути способ реализации того, что уже предлагал тут Old, но он Вам не нравится...
Да то, что Old предлагал, как-то.... эээ.... он предлагает не блокироваться в selecte. Кагбы уже я наверно всё выяснил... так ... мысли терзают... как можно вообще читать без блокировки? как можно писать алгоритмы подобные Old? это же равносильно коду
Цитировать
while(1);
Объясню почему:

Цитировать
while(!isTimerOut() ||(bytesAvailable < 10) )
{
select(...);
}
только не совсем понятно зачем здесь селект или полл нужен.
Такая нить грузит процессор на все 100%. Конечно планировщик этой нити не даст 100% процессора... но все ровно нехилую долю нить отъест. А если этих нитей будет 500 в программе? А если будет запущенно 500 экземпляров программы? То ваш какойнить ARM, на котором крутиться кинукс - ляжет. (Тем более, что изначально у меня по ТЗ было ожидание 450 мс. Сегодня 70 мс, завтра 2 сек сделают.) Правильно говорит gate, в таких случаях нужен sleep(), сним нагрузка будет пренебрежительно мала. Но писал бы я какой-нить терминал (типа HyperTerminal), или делал бы чтение датчика температуры - тут бы слып мне помог... тут можно было бы не на 10 мс уснуть, а на 1 сек. Но у меня другой случай.
Пример с уартом... в том же линуксе не зря придумали блокирующее чтение (хотя способом Old можно легко обойтись и без блокирующего чтения перегружая проц). Т.е. настроил таймауты, вызвал read, поток уснёт до прихода n байт и процессор не будет постоянно проверять получение байт, а будет заниматься другими задачами. Есть аналогичные API для винды.
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

То что вы привели в качестве кода и близко не похоже на то, что пишет Old. Улыбающийся
Вам стоит лучше разобраться в том, как организуется пулинг в подобном программном обеспечении и тогда вам сразу станет понятно, о чем я говорю.
А блокирующий read можно использовать в лабораторках или небольших утилитках.
« Последнее редактирование: Январь 27, 2015, 17:13 от Old » Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


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