Настройка переносной общей библиотеки с циклом событий Qt

Мы пытаемся написать переносную разделяемую библиотеку, которая для удобства использует некоторые классы Qt (главным образом QTimer а также QTcpSocket); но без графического интерфейса. Соответствующие соединения сигнал / слот, по-видимому, требуют некоторой петли событий Qt, поэтому мы «заправляем» QCoreApplication как указано в этот ответ. Соответственно, мы устанавливаем рабочий объект, который выполняет тяжелую работу, и перемещаем его в QThread,

Проблема, с которой мы сейчас сталкиваемся, состоит в том, что очереди между QThreadобъект владельца (в основном потоке) и рабочий объект в пределах QThread похоже, никогда не обрабатывается в системах Linux, по крайней мере, до тех пор, пока программа, реализующая нашу библиотеку, не предоставляет какой-либо свой собственный цикл событий Qt в основном потоке. Это не очень полезно, поскольку данные, передаваемые рабочим в основной поток, должны передаваться дальше с использованием некоторых функций обратного вызова, которые теперь никогда не вызываются.

Мой вопрос таков: есть ли способ заставить цикл событий работать в главном потоке библиотеки, не блокируя его или не запуская основную программу (что, похоже, имеет место при установке QCoreApplication::exec() или подобное там)? Или нам нужно будет установить другую схему связи между потоками (независимо от Qt), чтобы справиться с этими передачами данных?

Поскольку мы не знаем, будет ли программное обеспечение хоста работать на QApplication или нет, в идеале я бы также проверил это перед настройкой цикла событий основного потока. Простой if(qApp != nullptr) достаточно для этого?

П.С .: Несколько вещей, которые я пробовал, но у меня тоже ничего не получалось:

  • Настройки до QEventLoop в std::thread запускается из основного потока (вероятно, не работает, потому что все еще не в основном потоке)
  • Настройка QEventLoop в классе основного потока и запуска его processEvents() функционировать периодически, используя QTimer (вероятно, не работает из-за отсутствия цикла событий для QTimer::timeout сигнал в основной функции)
  • Начиная QCoreApplication в std::thread (выдает предупреждение во время выполнения в Windows, что QCoreApplication должен быть запущен в главном потоке)

0

Решение

На языке Qt обратный вызов называется Qt::DirectConnection, Но, конечно, эти обратные вызовы будут выполняться в вашем рабочем потоке. Но это было бы в случае с любой другой библиотекой, которая использует обратные вызовы, поэтому Qt здесь не является проблемой, как и ваш код: основная идея имеет это свойство.

Если хост-приложение не использует цикл обработки событий (любой цикл обработки событий, не обязательно Qt), то вы ничего не можете сделать, кроме опроса — см. Ниже.

Если хост-приложение запускает цикл событий X11, вам нужно убедиться, что ваша копия Qt использует тот же базовый цикл событий, что и хост-приложение. Обычно это цикл событий glib, и тогда он должен работать автоматически. В противном случае вам нужно будет передать пользователю файловый дескриптор примитива синхронизации, используемого циклом событий Qt, и пользователю нужно будет интегрировать его в свой цикл событий. Вы столкнетесь с той же проблемой, используете ли вы Qt или нет: использование собственного метода связи не исправит его, поскольку вам все еще нужен ожидаемый примитив, который будет взаимодействовать с любым циклом событий, который использует пользователь.

Пользователь может, конечно, опросить обратные вызовы, когда захочет: выставить mainPoll() метод, который направляет QCoreApplication::processEvents(),

0

Другие решения

Несмотря на принятие другого ответа (который я считаю более правильным), я все же хотел бы упомянуть обходной путь, который работал на удивление хорошо: нам фактически удалось обойти проблемы цикла / потока событий в большинстве систем, соединив сигналы рабочего потока с лямбда-функциями в конструкторе класса, который устанавливает рабочий.

Теперь я сомневаюсь, что это поведение правильно поточно-ориентированное и имеет относительно длинные лямбда-функции, объявленные в connect вызовы функций, конечно, не хороший стиль. Но в случае, если кто-то еще столкнется с этой проблемой, это может быть краткосрочное решение или (временный) обходной путь.

0

По вопросам рекламы [email protected]