Решения по замене соединений Qt для сигнальных слотов (через границы потоков)? - PullRequest
0 голосов
/ 29 апреля 2020

В Qt можно:

connect(object, &Object::someSignal, objectInAnotherThread, &Object::someSlot);

Итак, когда я подключаю сигнал от объекта в потоке к объекту в другом потоке, Qt ставит в очередь сигнал, и someSlot будет выполняться в поток объекта InAnotherThread .

Эта особенность очень удобна и безопасна, хотя может копировать данные.

Лямбды в C ++ 11 удобны, но при замене этого типа соединения с помощью чистого лямбда-обратного вызова (без Qt ), лямбда будет исполнена в потоке вызывающей стороны . Это обычно требует мьютексов и c склонных к ошибкам логи c, чтобы все исправить.

Мне известно о Boost::signals2 et c, но AFAIK они не предоставляют этого же Поведение, подобное Qt, когда используется через границы потоков ..?

Если я хотел бы удалить Qt по той или иной причине, какие у меня есть варианты для замены в отношении моих соединений сигнальных слотов?

1 Ответ

1 голос
/ 30 апреля 2020

Что не так с раскруткой потока и посылкой вызовов обернутых функций в очередь, из которой поток извлекает и выполняет? Очередь событий в Qt не очень особенная, за исключением того, что она использует «родное» событие l oop. Однако в этом нет необходимости, и, например, потоки QtConcurrent :: run реализуют простую очередь, защищенную условием mutex + wait. Всякий раз, когда доставляются новые события, поток просыпается и обрабатывает их, пока очередь не опустеет. События могут нести вызовы функторов. Фактически, события могут быть просто std :: function. Единственным камнем преткновения являются таймеры, которые вам нужно реализовать поверх примитива, ожидающего при условии ожидания. У этих ожиданий есть тайм-ауты, и вы будете использовать отсортированную очередь тайм-аутов и расписание пробуждений всякий раз, когда объект таймера «тикает». Преимущество этого состоит в том, что вы не используете никаких встроенных таймеров и потенциально можете работать лучше.

...