Является ли цикл обработки событий Qt безопасным или атомарным?Как это синхронизируется при работе с `QueuedConnection`? - PullRequest
1 голос
/ 10 апреля 2019

Предположим, что 2 QThread s работают со следующим соотношением:

connect(&Object1OfThread1, &Object1::Signal, 
        &Object2OfThread2, &Object2::Slot, Qt::QueuedConnection);

Таким образом, когда объект из одного потока генерирует сигнал, вызывается слот другого потока. Как обсуждалось в сигналах Qt (QueuedConnection и DirectConnection) , из-за Qt::QueuedConnection, Signal() публикуется / добавляется в цикл обработки событий Thread2. Когда наступает очередь, вызывается Slot().

Вопрос : Является ли сам цикл обработки событий потокобезопасным?
а именно Что делать, если Thread1 и Thread3 одновременно отправляют сигнал в цикл событий Thread2.

Ответы [ 2 ]

1 голос
/ 12 апреля 2019

Цикл событий Qt является потокобезопасным, но не атомарным.

Безопасность потока

Пока состояние Object2OfThread2 всегда изменяется потоком, связанным с Thread2, условий гонки не будет.Не более одного слота будет выполнено в любое время.

Атомность

Порядок исполнения слотов определяется:

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

Поэтому я бы не советовал предполагать конкретный порядок исполнения для данного слота.

чтоесли Thread1 и Thread3 одновременно отправляют сигнал в цикл событий Thread2

  • Во-первых, это разные сигналы: два потока не могут излучать один и тот же сигнал одного и того же объекта, так как этот объект находится только в одномQObject
  • Сигнал, подключенный первым, выигрывает , при условии, что эти сигналы подключены только к Object2OfThread2, даже если они "отправлены" одновременно.
  • Если, например, сигналы Thread1 являютсяподключены к другим сигналам \ слотам, и эти подключения выполняются до Object2OfThread2, &Object2::Slot, они будут обработаны перед отправкой в ​​цикл событий Object2OfThread2.Если сигналы испускаются одновременно, сигнал Thread3 будет первым в очереди, поэтому первым будет выполняться.
1 голос
/ 11 апреля 2019

В статье, упомянутой в этом комментарии , говорится, что очередь событий защищена мьютексом.

Как работают сигналы и слоты Qt - Часть 3. Соединения в очереди и между потоками

A QueuedConnection отправит событие в цикл событий для последующей обработки.

При публикации события (в QCoreApplication::postEvent) событие будет помещено в очередь для потока (QThreadData::postEventList). Очередь событий защищена мьютексом, поэтому нет условий гонки, когда потоки помещают события в очередь событий другого потока .

Как только событие было добавлено в очередь, и если получатель живет в другом потоке, мы уведомляем диспетчера событий этого потока, вызывая QAbstractEventDispatcher::wakeUp. Это разбудит диспетчера, если он спал, ожидая новых событий. Если получатель находится в том же потоке, событие будет обработано позже, так как цикл события повторяется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...