Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: boriska от Декабрь 11, 2012, 11:18



Название: ожидание события, потоки
Отправлено: boriska от Декабрь 11, 2012, 11:18
здрасте, пишу программу под линукс с помощью qt.
подскажите аналог WinApi функции WaitForSingleOject().
дело в том, что есть два не-GUI потока, которые крутятся в бесконечном цикле.
поток №2 перед началом выполнению очередного цикла должен дождаться сигнала от потока №1.
на windows это было реализовано с помощью событий


Название: Re: ожидание события, потоки
Отправлено: ssoft от Декабрь 11, 2012, 11:24
Использовать общий QMutex.


Название: Re: ожидание события, потоки
Отправлено: kuzulis от Декабрь 11, 2012, 11:40
Цитировать
здрасте, пишу программу под линукс с помощью qt.
подскажите аналог WinApi функции WaitForSingleOject().
o_O лолчто? Ты хоть определись и конкретизируй ОС, а то на ЛОР-е ты не написал.

А так - QWaitCondition тебе уже на ЛОР-е подсказали. См. Qt-шные примеры.


Название: Re: ожидание события, потоки
Отправлено: Igors от Декабрь 11, 2012, 11:50
А так - QWaitCondition тебе уже на ЛОР-е подсказали.
QWaitCondition может "вынести моск". Для того что рассказал автор темы хорош QSemaphore


Название: Re: ожидание события, потоки
Отправлено: twp от Декабрь 11, 2012, 20:57
подскажите аналог WinApi функции WaitForSingleObject().
а с каким дескриптором используется WaitForSingleObject()?
Она может использоваться как с потоком так и с мютексом.
тогда соответсвенно нужно смотреть на классы QThread и QMutex, а может и QWaitCondition


Название: Re: ожидание события, потоки
Отправлено: Bepec от Декабрь 11, 2012, 22:41
QWaitCondition выносит мозг. Согласен с этим :)


Название: Re: ожидание события, потоки
Отправлено: Dancing_on_water от Декабрь 14, 2012, 21:01
Если время исполнение кода, который исполняется во втором потоке, после приема сигнала с первого, невелико, то пользовать QMutex (самый простой вариант в случае двух потоков).
Если время исполнения невелико как в первым, так и втором потоке,  то лучше смотреть в сторону QAtomicInt и QAtomicPointer и юзать неблокирующую синхронизацию.
 
Если исполняемый код большой, то лучше делать через синалы-слоты.
Пользовать семафор надо лишь в случае 3 и более потоков.

Короче, нужна конкретика.


Название: Re: ожидание события, потоки
Отправлено: Igors от Декабрь 14, 2012, 21:22
Короче, нужна конкретика.
Хорошо, вот простейшая задачка что соответствует изложенной в посте 1

- одна нитка ждет символ с клавиатуры (напр getchar), а другая этот символ печатает (напр printf)

Ваше решение?


Название: Re: ожидание события, потоки
Отправлено: Dancing_on_water от Декабрь 14, 2012, 21:32
Запихнул в один поток, оверхед на синхронизацию слишком велик.


Название: Re: ожидание события, потоки
Отправлено: Igors от Декабрь 14, 2012, 21:41
Запихнул в один поток, оверхед на синхронизацию слишком велик.
А у Вас нет выбора что куда пихать - нитка 1 умеет только читать, нитка 2 - только печатать. Да и сказки про ужасный оверхед рассказывать не стоит  :)


Название: Re: ожидание события, потоки
Отправлено: Dancing_on_water от Декабрь 14, 2012, 22:06
Сферически дурацкие задачи не решаю.
А оверхед для этой задачи жуткий: как не делай, но уже самое ожидания потока на выдачу займет больше процессорного времени, чем исполнение команды.
(это если предположить, что у нас на все про все есть один конвеер или раскидывание потоков по конвеерам мы не занимеамся)
Конечно, если предположить, что у нас уже есть два конвеера, и на одном сидит один поток и на другом другой. то стоит смотреть на неблокирующую синхронизацию си атомические типы.


Название: Re: ожидание события, потоки
Отправлено: Igors от Декабрь 14, 2012, 22:48
Сферически дурацкие задачи не решаю.
А оверхед для этой задачи жуткий: как не делай, но уже самое ожидания потока на выдачу займет больше процессорного времени, чем исполнение команды.
(это если предположить, что у нас на все про все есть один конвеер или раскидывание потоков по конвеерам мы не занимеамся)
Конечно, если предположить, что у нас уже есть два конвеера, и на одном сидит один поток и на другом другой. то стоит смотреть на неблокирующую синхронизацию си атомические типы.
Ой наплели "с три короба" - вместо того чтобы написать неск строк кода :)  А atomic здесь вообще "як собацi п'ята лапа"  :)


Название: Re: ожидание события, потоки
Отправлено: Dancing_on_water от Декабрь 15, 2012, 08:06
Троллинг жирный, тоньше надо, тоньше.

Задача постановлена в терминах "а допустим". И ответ дан в том же ключе.

Насчет атомиков: а давно вы смотрели код синхронизирующих примитивов в qt? или код контейнеров?


Название: Re: ожидание события, потоки
Отправлено: Igors от Декабрь 15, 2012, 12:06
Задача постановлена в терминах "а допустим". И ответ дан в том же ключе.
Насчет ответа - то да. А вопрос был вполне нормальный
есть два не-GUI потока, которые крутятся в бесконечном цикле.
поток №2 перед началом выполнению очередного цикла должен дождаться сигнала от потока №1.
Вот простой способ это сделать
Код
C++ (Qt)
// thread 2
while (true) {
theSemaphore.acquire();
...
}
 
// thread 1
..
theSemaphore.release();
 
Конечно это не единственное решение, но в упор не вижу как это сделать на QMutex и причем тут atomic(и)  ???


Название: Re: ожидание события, потоки
Отправлено: Dancing_on_water от Декабрь 15, 2012, 12:42
Да, насчет QMutex это я сказанул (конструкции придумал, но вот где они могут быть использованы не понятно). Нужно юзать QWaitCondition.

А с атомиками можно придумать что-то типа такого:

Код:
глобально:
QAtomicInt buffer;

поток 1:

char tmp;

char = getchar();

buffer.fetchAndStoreOrdered(tmp);

поток 2:

while(1)
{
  if(buffer != -257)
  {
   std::cout<<buffer;
   buffer.fetchAndStoreOrdered(-257);
  }
}


Название: Re: ожидание события, потоки
Отправлено: Igors от Декабрь 15, 2012, 13:10
Нужно юзать QWaitCondition.
Ну так код предъявляем  :)

А с атомиками можно придумать что-то типа такого:
Если ожидание ввода от пользователя (или вообще ожидание может быть долгим) то жечь процессор не есть хорошо, atomic не к месту. А реализация не рабочая
Код
C++ (Qt)
buffer.fetchAndStoreOrdered(tmp);
// нитка 1 сейчас здесь, записала в buffer новое значение
 
...
// нитка 2 активировалась и перетирает записанное
  buffer.fetchAndStoreOrdered(-257);
}
Ну ничего, на такие грабли наступают все - и очень много раз  :)


Название: Re: ожидание события, потоки
Отправлено: Dancing_on_water от Декабрь 15, 2012, 14:26
Цитировать
Ну так код предъявляем
http://doc.qt.digia.com/qt/qwaitcondition.html

Цитировать
Если ожидание ввода от пользователя (или вообще ожидание может быть долгим) то жечь процессор не есть хорошо, atomic не к месту.
Вы придумали абстрактный пример и ввели искусственные ограничения, а теперь говорите о уместности\неуместности. Да блинский блин, одно уже переключение шедулера тут неуместно!

Цитировать
А реализация не рабочая
Я рад, что вы заметили. Но я сказал:
Цитировать
А с атомиками можно придумать что-то типа такого
. Я не придрался, но раз хотите, то и вами предложенный вариант может работать некорректно: может так случиться, что мы пойдем на чтение раньше, чем начнем выводить.


Название: Re: ожидание события, потоки
Отправлено: Igors от Декабрь 15, 2012, 15:17
http://doc.qt.digia.com/qt/qwaitcondition.html
Ну и чего тыкать в нос ссылкой на букварь? :) Вас спрашивали как это применить, класс-то все знают. Кстати заметили ли Вы что приводимый там пример некорректен?

Вы придумали абстрактный пример и ввели искусственные ограничения, а теперь говорите о уместности\неуместности. Да блинский блин, одно уже переключение шедулера тут неуместно!
Не злитесь, задачка самая рядовая и в жизни встречается частенько. Я понимаю что atomic - это реально трудно. Хотите я напишу а Вы будете искать ошибку?  :)


Название: Re: ожидание события, потоки
Отправлено: Dancing_on_water от Декабрь 16, 2012, 13:47
Цитировать
Ну и чего тыкать в нос ссылкой на букварь?  Вас спрашивали как это применить, класс-то все знают. Кстати заметили ли Вы что приводимый там пример некорректен?
Эээээ, если честно, из описания класса понятно как его применить в подобной ситуации. Пример там приведен описательный, для понимания сути, а не для того, чтобы копипастить.

Цитировать
Не злитесь, задачка самая рядовая и в жизни встречается частенько. Я понимаю что atomic - это реально трудно. Хотите я напишу а Вы будете искать ошибку?
Злиться не умею. Просто свято верю в то, что у человека голова на плечах есть, и если ему подсказать, то он сам додумает до правильного решения. Атомики это не сложнее чем любой другой многопоточный код. Просто у них своя специфика. А приведенный пример вами, в реальной жизни я не встречал ни разу. Чтение данных в одном потоке, а работа с ними в другом - сплошь и рядом.  Но покажите мне того идиота, кто обработку одного char-а запихнет в иной поток, я ему пришью руки на место.

Возвращаясь к корректности моей и вашей синхронизации, то они совершенно корректны Все наши придирки из серии: "а что, если мы получим символ раньше чем его выведем на экран?". Так вот максимальная скорость набора: 400 символов в минуту, т.е. не лучше 1 символа в 100 мс, квант времени ~10 мс, это значит, что за это время шедулер точно успеет выйти из потока-приемника, а вероятность не попадания в поток-обработчик возникнет только при высокой нагрузке. Однако, при высокой нагрузке возникнет вероятность и пропуска сигналы с клавиатуры уже системой.


Название: Re: ожидание события, потоки
Отправлено: Igors от Декабрь 16, 2012, 16:01
Эээээ, если честно, из описания класса понятно как его применить в подобной ситуации.
Ну если Вам понятно, то и приведите код, в чем загвоздка?  :)

Атомики это не сложнее чем любой другой многопоточный код.
Я не хочу Вас обидеть, но согласитесь - пока общие слова, а рабочего кода нет. И предчувствие что Ваш следующий ответ опять будет только из общих слов. Или я не прав? Предложили atomic'и (не знаю зачем) - покажите на деле, а не так, "с пятого на десятое", мол, можно и atomic'и - что можно, то всем известно.

А приведенный пример вами, в реальной жизни я не встречал ни разу. Чтение данных в одном потоке, а работа с ними в другом - сплошь и рядом. 
Так вот именно. Разумеется в реальной задаче будут совсем не getchar и не printf - но суть та же самая. Поэтому ни к чему вдаваться в анализ скорости клавы - программист может и должен уметь думать более широко, абстрактно (там где надо)


Название: Re: ожидание события, потоки
Отправлено: Dancing_on_water от Декабрь 17, 2012, 09:09
Цитировать
Ну если Вам понятно, то и приведите код, в чем загвоздка?
Честно, говоря то все больше напоминает троллинг (правда уже тоньше. Если из доки сне следует что-то подобное, то я в шоке.  ???

Код:
//глобально 
QWaitСondition waitCondition;

//поток 1
getchar();
waitcondition.wakeAll();

//поток 2
QMutex mutex;
mutex.lock();
waitcondition.wait(&mutex);
mutex.unlock();
fprintf();

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


Название: Re: ожидание события, потоки
Отправлено: Igors от Декабрь 17, 2012, 17:13
Если из доки сне следует что-то подобное, то я в шоке.  ???

Код:
//глобально 
QWaitСondition waitCondition;

//поток 1
getchar();
waitcondition.wakeAll();

//поток 2
QMutex mutex;
mutex.lock();
waitcondition.wait(&mutex);
mutex.unlock();
fprintf();
a) Батенька, а куда же делся тот char который Вы считали getchar? Почему он не напечатан?
b) Перед wakеAll надо захватывать mutex, а после - освобождать (ну ладно, то Вы описАлись)
с) Даже с учетом сказанного - все равно неправильно, число печатей может быть меньше числа считываний.
d) Что значит "что-то подобное"? Это рабочий код или как? Если нет, то зачем его приводить?

Честно, говоря то все больше напоминает троллинг
Я вижу весьма самонадеянного (вероятно молодого) человека, который довольно резво/категорично обо всем судит. И я предложил ему показать свои умения на очень простой задачке
одна нитка ждет символ с клавиатуры (напр getchar), а другая этот символ печатает (напр printf)
Молодой человек долго извивался, но сделать это ни на одном из примитивов синхронизации так и не смог. Поэтому о "троллинге" ему бы лучше помолчать. И заявления чего там программист должен не очень-то вяжутся с беспомощным плаванием в десятке строк кода.


Название: Re: ожидание события, потоки
Отправлено: Dancing_on_water от Декабрь 17, 2012, 19:30
Цитировать
Молодой человек долго извивался, но сделать это ни на одном из примитивов синхронизации так и не смог. Поэтому о "троллинге" ему бы лучше помолчать. И заявления чего там программист должен не очень-то вяжутся с беспомощным плаванием в десятке строк кода.
Я-то, по наивности думал, что тут нужно топикстартеру помочь, или облегчить жизнь другим, кто будет читать эту тему. Что тут можно поделиться своим скудным опытом, самому узнать что-то новое. Но, попал на ярмарку тщеславия. Хотя не скажу что внезапно, ход беседы к тому и вел.

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

P.S. Перечитал тред. Вы такой забавный.  ;D


Название: Re: ожидание события, потоки
Отправлено: Bepec от Декабрь 17, 2012, 20:27
Кхм. Dancing_on_water - рабочий проект в студию.

Я лично когда разбирался с QWaitCondition скурил выпил весь запас китайского чая (300 граммов). И то до сих пор не понимаю, каким чудом там все работает :D


Название: Re: ожидание события, потоки
Отправлено: Dancing_on_water от Декабрь 17, 2012, 21:34
Ну блин, а копнуть исходник qt слабо? Что касается принципиальной схемы реализации, то для винды там стоит WaitForSingleObject.

Логику зачем обязали перед вызовом захватывать mutex  я понимаю с трудом (считай есть только догадки)

Насчет юзанью: выше я привел схему. Она у меня вполне работает при иницилизации приложения.

т.е. строго по доке:

поток 1:

захват мутекса
wait
отпускаем мьютекс

поток 2:

wake


Название: Re: ожидание события, потоки
Отправлено: Bepec от Декабрь 17, 2012, 21:46
Т.е. вы швыряетесь громкими словами об использовании QWaitCondition, а сами не в силах освоить тег code на форуме? :P


Название: Re: ожидание события, потоки
Отправлено: Dancing_on_water от Декабрь 17, 2012, 22:01
Тегом я пользоваться умею. Если соизволите пролистать вверх, то все сами увидите, господин.
Просто то, что я счас написал на код уж совсем не подходит.

Кстати, замечу, в Вашем посте ни слова по теме.


Название: Re: ожидание события, потоки
Отправлено: Bepec от Декабрь 18, 2012, 08:05
А что толку бодаться с вами? :) Если уж Igors вас не перебодал, мне чего стараться?