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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QT - цикл обработки событий.  (Прочитано 12022 раз)
Базиля
Гость
« : Октябрь 25, 2013, 00:47 »

Здравствуйте!

Назрел такой вопрос, а точнее есть недопонимание одного момента.

Допустим, что имеется 2 потока, у каждого из них по своему циклу обработки событий.
Потоки обмениваются информацией с помощью сигналов и слотов. Соответственно сигнал при поступлении к объекту получателю, преобразуется в событие и встает в очередь обработки событий данного объекта.

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

Что касается самой практики - не доходят все сигналы (это чтобы ясней стало, в чем именно заключается сам вопрос ).
К примеру, если объект получатель был долгое время недоступен (занимался вычислениями или просто "спал"), то из всех поступающих в этот момент сигналов (их было около 300) - пропало 30.
Т.е. они просто не дошли до объекта получателя, с чем это может быть связано?
Почему тогда остальные соизволили добраться до объекта?

Просмотрел всю документацию и книги по данному вопросу, почему-то именно этот момент не рассматривается.
Остается только как-то домысливать самому, но что-то видать не совсем это правильно получается.

Спасибо!
Записан
carrygun
Гость
« Ответ #1 : Октябрь 25, 2013, 05:20 »

По идее сигналы должны вставать в очередь событий объекта, который принимает эти сигналы, пока она не переполнится. Если этот объект сильно занят, а сигналы нужно обработать, то можно попробовать воспользоваться qApp->processEvents();.
Записан
mutineer
Гость
« Ответ #2 : Октябрь 25, 2013, 08:28 »

Сигналы стоят в очереди у потока-получателя. Потеря может быть связана с ограниченной длиной очереди, например.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Октябрь 25, 2013, 08:54 »

Допустим, что имеется 2 потока, у каждого из них по своему циклу обработки событий.
Потоки обмениваются информацией с помощью сигналов и слотов. Соответственно сигнал при поступлении к объекту получателю, преобразуется в событие и встает в очередь обработки событий данного объекта.
Ну не то чтобы "преобразуется", принимается все равно сигнал (не event), но да, сигнал будет ждать в eventLoop того QThread которой получатель принадлежит. Никаких потерь быть не должно. Если поток непрерывно занят, то, как уже сказали, он может позаботиться сам о сигналах вызывая processEvents. Конечно речь идет только о queuedConnection
Записан
Базиля
Гость
« Ответ #4 : Октябрь 25, 2013, 13:34 »

carrygun
mutineer
Igors
Спасибо за ответы!
Извиняюсь, проблема была в совершенно другом куске кода, с сигналами все нормально  Улыбающийся

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

На практике все работает, но в теории разобраться хочется  Смеющийся

Благодарю!
Записан
mutineer
Гость
« Ответ #5 : Октябрь 25, 2013, 13:45 »

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

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Октябрь 25, 2013, 13:52 »

Ведь сам цикл обработки принадлежит объекту.
QEventLoop - это локальная переменная в методе QThread::exec (QApplication::exec для главной нитки). QObject всегда знает "свою" нитку, а та знает свой QEventLoop который сейчас крутится. Сигнал остается в QEventLoop пока не извлечется. Об ограничениях размера очереди мне ничего не известно
Записан
Базиля
Гость
« Ответ #7 : Октябрь 25, 2013, 14:20 »

Очередь сообщений это структура данных и положить в нее новый ивент можно из вызывающего потока
Правильно ли утверждать, что объект этой структуры относится к объекту (а именно потоку), который и запустил цикл обработки событий?
Тогда ведь в таком случае, какой поток будет отвечать за доступ к объекту нашей очереди, если сам поток (родитель этого объекта) сейчас занят?

Ведь сам цикл обработки принадлежит объекту.
QEventLoop - это локальная переменная в методе QThread::exec (QApplication::exec для главной нитки). QObject всегда знает "свою" нитку, а та знает свой QEventLoop который сейчас крутится. Сигнал остается в QEventLoop пока не извлечется.
А доступ к этой переменной (я так полагаю это и есть наша очередь?) осущ. через поток, который и запустил цикл обработки событий?

Цитировать
Об ограничениях размера очереди мне ничего не известно
А на практике бывали случаи переполнения?
Записан
mutineer
Гость
« Ответ #8 : Октябрь 25, 2013, 14:23 »

Очередь сообщений это структура данных и положить в нее новый ивент можно из вызывающего потока
Правильно ли утверждать, что объект этой структуры относится к объекту (а именно потоку), который и запустил цикл обработки событий?
Тогда ведь в таком случае, какой поток будет отвечать за доступ к объекту нашей очереди, если сам поток (родитель этого объекта) сейчас занят?

Данные сами по себе не относятся ни к какому потоку. Поток это последовательность выполнения инструкций, данные это область в памяти. К памяти можно обращаться из любого потока одного и того же процесса
Записан
Базиля
Гость
« Ответ #9 : Октябрь 25, 2013, 14:27 »

Данные сами по себе не относятся ни к какому потоку. Поток это последовательность выполнения инструкций, данные это область в памяти. К памяти можно обращаться из любого потока одного и того же процесса
Говоря поток, я подразумеваю сам объект, который исполняется в отдельном потоке.
Ведь все данные принадлежат к какому-то объекту, сама очередь будет принадлежать объекту который ее и запустил? Правильно?

P.S. Я понял в какую вы сторону клоните, но все равно какая-то каша в голове Грустный
Получается что сигнал в очередь положит сам объект, который его и испустил?
« Последнее редактирование: Октябрь 25, 2013, 14:33 от Базиля » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #10 : Октябрь 25, 2013, 14:31 »

Ведь сам цикл обработки принадлежит объекту.
Нет, очередь событий принадлежит контексту потока. У любого QObject (и соответственно всех его наследников) есть указатель на контекст той нити, которой принадлежит объект. Поэтому, зная указатель на объект, Qt всегда можем добраться до контекста нити и ее очереди событий.

QEventLoop - это локальная переменная в методе QThread::exec (QApplication::exec для главной нитки).
И что? Вы можете создать 100500 экземпляров QEventLoop в любых местах (не только в exec), и они все будут работать с одной очередью.
Записан
mutineer
Гость
« Ответ #11 : Октябрь 25, 2013, 14:32 »

Говоря поток, я подразумеваю сам объект, который исполняется в отдельном потоке.

Объект не исполняется в каком-то потоке. В рамках Qt если объект "принадлежит" потоку, то это значит что все события для этого объекта идут через очередь событий конкретного потока. Но если методы этого объекта вызвать напрямую, то исполнятся они в вызывающем потоке
Записан
Базиля
Гость
« Ответ #12 : Октябрь 25, 2013, 14:46 »

Объект не исполняется в каком-то потоке. В рамках Qt если объект "принадлежит" потоку, то это значит что все события для этого объекта идут через очередь событий конкретного потока. Но если методы этого объекта вызвать напрямую, то исполнятся они в вызывающем потоке
Это понятно, спасибо Улыбающийся
С этим я согласен  Смеющийся

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

Нет, очередь событий принадлежит контексту потока. У любого QObject (и соответственно всех его наследников) есть указатель на контекст той нити, которой принадлежит объект. Поэтому, зная указатель на объект, Qt всегда можем добраться до контекста нити и ее очереди событий.
А сам тогда цикл обработки где исполняется?
« Последнее редактирование: Октябрь 25, 2013, 14:48 от Базиля » Записан
mutineer
Гость
« Ответ #13 : Октябрь 25, 2013, 14:48 »

И вот теперь самый вопрос, из-за которого у меня в голове все недоразумения в моей голове, если поток сейчас занят вычислениями, кто занесет в его очередь поступающий сигнал?

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

Сообщений: 4350



Просмотр профиля
« Ответ #14 : Октябрь 25, 2013, 14:52 »

Верно ли я понял, что очередь событий принадлежит конкретному потоку?

если поток сейчас занят вычислениями, кто занесет в его очередь поступающий сигнал?
Один поток занят, а другой поток, как раз занимается тем, что лезет в очередь событий (это структура данных как вектор, список и т.д.)  первого потока и кладет туда нужное событие. Улыбающийся

А сам тогда цикл обработки где исполняется?
В каком смысле где? В коде, который выполняется в нужном потоке.
« Последнее редактирование: Октябрь 25, 2013, 14:55 от Old » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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