Russian Qt Forum

Qt => Общие вопросы => Тема начата: Waryable от Октябрь 06, 2010, 06:20



Название: Поиск события обработки сигнала из другого потока
Отправлено: Waryable от Октябрь 06, 2010, 06:20
Всем привет. Исходные данные для примера:
- есть два потока(Thread1, Thread2)
- между ними есть связь: сигнал из  Thread1 вызывает слот Thread2
- слот Thread2 работает с данными принадлежащими Thread2
- сам Thread2 постоянно крутится в цикле, модифицируя свои данные

Ситуация: возбуждаю я сигнал. Если тип связи указан Qt::AutoConnection, то по всем правилам соединение получается Qt::DirectConnection(в данном случае можно было явно указать этот тип связи). Т.о. сигнал выполняяется на стороне Thread2, а значит попадает в очередь событий этого потока. Вот тут и проявляется небольшой(а может быть и большой) пробел в моих познаниях. В какой момент поток извлекает событие из очереди событий? Другими словами хочется знать что является в данном контексте атомарными действиями, между которыми можно вставлять обработку событий?
В манах толей есть описание работы очередей потоков, но в нем я не нашел точного ответа. Там буквально написано следующее(ссылка на ман: http://doc.qt.nokia.com/4.6/signalsandslots.html):
Цитировать
When a signal is emitted, the slots connected to it are usually executed immediately, just like a normal function call. When this happens, the signals and slots mechanism is totally independent of any GUI event loop. Execution of the code following the emit statement will occur once all slots have returned. The situation is slightly different when using queued connections; in such a case, the code following the emit keyword will continue immediately, and the slots will be executed later.
Вот и стал интересен "размер" этого later.

ЗЫ: буду рад ссылкам на соответствующую лит-ру.


Название: Re: Поиск события обработки сигнала из другого потока
Отправлено: SABROG от Октябрь 06, 2010, 08:23
Если тип связи указан Qt::AutoConnection, то по всем правилам соединение получается Qt::DirectConnection(в данном случае можно было явно указать этот тип связи).
Тут видимо опечатка, т.к. по всем правилам между потоками получается какраз Qt::QueuedConnection.

В какой момент поток извлекает событие из очереди событий? Другими словами хочется знать что является в данном контексте атомарными действиями, между которыми можно вставлять обработку событий?
В момент вызова таких методов как QEventLoop::exec(), QThread::exec(), QCoreApplication::exec(), QCoreApplication::processEvents() и при возвращении в основной цикл событий, когда происходит возвращение управления из метода потока.

Поэтому later может никогда и не наступить, если внутри метода сделать бесконечный цикл for(;;) и при этом не вызывать никаких выше перечисленных методов для обработки накопившихся эвентов.


Название: Re: Поиск события обработки сигнала из другого потока
Отправлено: Waryable от Октябрь 06, 2010, 10:40
Цитировать
Тут видимо опечатка, т.к. по всем правилам между потоками получается какраз Qt::QueuedConnection.
Да извиняюсь. Тут, естественно, опечатка.
Цитировать
В момент вызова таких методов как QEventLoop::exec(), QThread::exec(), QCoreApplication::exec(), QCoreApplication::processEvents() и при возвращении в основной цикл событий, когда происходит возвращение управления из метода потока.
Странно. Создал приложение с двумя потоками: основной поток и поток в котором крутится именно такой цикл:
Код:
for(;;);
Так вот второй поток прекрасно принимает сигналы из главного потока. Получается, что происходит неявный вызов *::exec(), либо QCoreApplication::processEvents(). Ну либо я чего-то недопонимаю...
Начал копать еще глубжее и мне показалось, что недопонимание у меня не в работе Qt. Может кто кинет ссыль на толковую статейку на счет организации очереди событий виндовоза? Погуглил и кроме хлама и плагиата на хлам ничего не нашел.


Название: Re: Поиск события обработки сигнала из другого потока
Отправлено: MoPDoBoPoT от Октябрь 06, 2010, 10:51
Тут видимо опечатка, т.к. по всем правилам между потоками получается какраз Qt::QueuedConnection.
По-моему в данном случае будет Qt::DirectConnection, так как эти потоки созданы в главном и, соответственно, они в нём и живут (если, конечно, для них не был сделан QObject::moveToThread()).


Название: Re: Поиск события обработки сигнала из другого потока
Отправлено: MoPDoBoPoT от Октябрь 06, 2010, 10:52
Странно. Создал приложение с двумя потоками: основной поток и поток в котором крутится именно такой цикл:
Код:
for(;;);
Так вот второй поток прекрасно принимает сигналы из главного потока.
А это, вроде как, подтверждение моих слов.


Название: Re: Поиск события обработки сигнала из другого потока
Отправлено: SABROG от Октябрь 06, 2010, 10:59
По-моему в данном случае будет Qt::DirectConnection, так как эти потоки созданы в главном и, соответственно, они в нём и живут (если, конечно, для них не был сделан QObject::moveToThread()).

Наверное ты прав. Qt::QueuedConnection был бы, если бы третий поток (второй QThread) создавался внутри QThread::run() первого дочернего потока.

Начал копать еще глубжее и мне показалось, что недопонимание у меня не в работе Qt. Может кто кинет ссыль на толковую статейку на счет организации очереди событий виндовоза? Погуглил и кроме хлама и плагиата на хлам ничего не нашел.
Очереди в Qt и Windows немного разные вещи. Если основной цикл событий в потоке заморожен, то сообщения винды или X11 кладутся в очередь и ожидают пока основной цикл событий не возобновит свою работу.


Название: Re: Поиск события обработки сигнала из другого потока
Отправлено: Waryable от Октябрь 06, 2010, 11:31
По-моему в данном случае будет Qt::DirectConnection, так как эти потоки созданы в главном и, соответственно, они в нём и живут (если, конечно, для них не был сделан QObject::moveToThread()).
Не должно быть так. Иначе теряется thread-safe.


Название: Re: Поиск события обработки сигнала из другого потока
Отправлено: MoPDoBoPoT от Октябрь 06, 2010, 14:35
В каком контексте будет вызван слот (http://www.forum.crossplatform.ru/index.php?showtopic=2910)


Название: Re: Поиск события обработки сигнала из другого потока
Отправлено: Waryable от Октябрь 07, 2010, 05:39
Спасибо за подсказаньки. С контекстами я разобрался. Но мне пока не удалось найти информацию о том, в какой момент поток извлекает событие из очереди событий.