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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Поиск события обработки сигнала из другого потока  (Прочитано 5410 раз)
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.

ЗЫ: буду рад ссылкам на соответствующую лит-ру.
« Последнее редактирование: Октябрь 06, 2010, 06:22 от Waryable » Записан
SABROG
Гость
« Ответ #1 : Октябрь 06, 2010, 08:23 »

Если тип связи указан Qt::AutoConnection, то по всем правилам соединение получается Qt::DirectConnection(в данном случае можно было явно указать этот тип связи).
Тут видимо опечатка, т.к. по всем правилам между потоками получается какраз Qt::QueuedConnection.

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

Поэтому later может никогда и не наступить, если внутри метода сделать бесконечный цикл for(;Подмигивающий и при этом не вызывать никаких выше перечисленных методов для обработки накопившихся эвентов.
Записан
Waryable
Гость
« Ответ #2 : Октябрь 06, 2010, 10:40 »

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

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

Странно. Создал приложение с двумя потоками: основной поток и поток в котором крутится именно такой цикл:
Код:
for(;;);
Так вот второй поток прекрасно принимает сигналы из главного потока.
А это, вроде как, подтверждение моих слов.
Записан
SABROG
Гость
« Ответ #5 : Октябрь 06, 2010, 10:59 »

По-моему в данном случае будет Qt::DirectConnection, так как эти потоки созданы в главном и, соответственно, они в нём и живут (если, конечно, для них не был сделан QObject::moveToThread()).

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

Начал копать еще глубжее и мне показалось, что недопонимание у меня не в работе Qt. Может кто кинет ссыль на толковую статейку на счет организации очереди событий виндовоза? Погуглил и кроме хлама и плагиата на хлам ничего не нашел.
Очереди в Qt и Windows немного разные вещи. Если основной цикл событий в потоке заморожен, то сообщения винды или X11 кладутся в очередь и ожидают пока основной цикл событий не возобновит свою работу.
Записан
Waryable
Гость
« Ответ #6 : Октябрь 06, 2010, 11:31 »

По-моему в данном случае будет Qt::DirectConnection, так как эти потоки созданы в главном и, соответственно, они в нём и живут (если, конечно, для них не был сделан QObject::moveToThread()).
Не должно быть так. Иначе теряется thread-safe.
Записан
MoPDoBoPoT
Гость
« Ответ #7 : Октябрь 06, 2010, 14:35 »

В каком контексте будет вызван слот
Записан
Waryable
Гость
« Ответ #8 : Октябрь 07, 2010, 05:39 »

Спасибо за подсказаньки. С контекстами я разобрался. Но мне пока не удалось найти информацию о том, в какой момент поток извлекает событие из очереди событий.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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