100 строк где-то в первых строках высылается сигнал emit signal(), то когда в рантайме его получит обработчик этого сигнала, относительно выполнения самого emit? То бишь сигнал выслан в первых строках функции или метода по ходу выполнения, то не будет ли он обработан только тогда, когда в этой функции будут выполнены все строки кода? Да я вот не знаю, как это реализовать не костыльно: мне нужно отправить из одного объекта сигнал в другой объект, и тут же получить результат выполнения обработки этого сигнала. У меня в одном потоке выполняется логика, игровой цикл, обычный while, где множество разных step-ов реализовано с помощью switch (case). В этом игровом цикле у меня используется задержки delay (), реализованные с помощью QEventLoop, именно поэтому игровой цикл реализован в отдельном потоке, чтобы не завешивать ввод/вывод и GUI. На данном этапе я реализовал такой костыль:в момент инициализации MainWindow он создаёт объект в памяти, указатель на который я передаю в конструкторы обоих классов, в одном из которых находится слот-обработчик, а во втором классе игровой цикл, который является источником сигнала. Я высылаю сигнал, слот обработчик получает его, сохраняет результат в мой shared-обьект, а отправитель сигнала с задержкой читает из объекта результат. Можно было бы сделать блокирующий вызов, но зависнуть в моем случае более критично, чем получить от обработчика не совсем корректные(или устаревшие) данные. Суть в том, что в моей игровой логике мне нужно прочитать данные из входа, для чего нужно сделать реквест с помощью модбаса, получить значение входа и от этого зависит дальнейший ход выполнения программы.
Может Вам в сторону QFuture посмотреть, если правильно понял проблему
Ему нужно СИНХРОННО получить результат.
у меня такое ощущение, что изначально неверный посыл, о том, что QEventLoop вешает главный поток породил кучу производных проблем. Начать хотя бы с того, что непонятно зачем реализовывать в потоке задержку при помощи эвентлупа. Это как молотком шурупы закручивать. Ну и почему всё-таки эвент луп должен вешать главный поток - совершенно непонятно
Сам по себе QEventLoop вообще никакой работы не выполняет
вот и вопрос: зачем он нужен если он никакой работы не выполняет? Не используете ли вы негодный инструмент для неподходящей задачи?
У меня подвешивал. Любой код внутри эвент лупа вызывается внутри обработки эвента и есть такое ощущение, что при запуске nested-лупа, тот тип эвента, который обрабатывался, встаёт в какую-то очередь и больше не приходит
какие-то специфические ситуации возможны всегда, но это надо постараться, потому-что в большинстве случаев использования никакого зависания главного потока не происходит
Мне каждый раз когда надо было превратить асинхронщину в синхронщину, подвешивало UI
Все что происходит после запуска app.exec() крутится в цикле событий Qt и GUI тоже, чтобы что-то сделать синхронно в Qt надо исходить из этого и пользоваться этим. Понятно что обычный sleep или waitForRead с порта, зафризит все потому что там реальный синхронны вызов идет минуя цикл событий Qt. Чтобы этого не происходило, как раз и используют локальные циклы событий, которые встраиваются в основной
Другими словами локальный луп позволяет выполнять операцию синхронно и при этом не блокирует луп потока?
Локальные циклы не спасут ни от sleep ни от wait. Локальные цикл - локальный мост между неким асинхронным процессом и ui циклом обработки сообщений, связанным signal/slot, позволяет локально дождаться результата без фриза ui, завершится и отпустить слот
Зачем ты это написал?
ну типа того, выше Анатолий как и я написал что от sleep и wait они не спасут, но все что подчиняется основному циклу событий, да спасет
можно еще корутины использовать, qcoro хороший проект
Я бы ещё добавил, что, по сути, он идентичен вызову в цикле processEvents
int QEventLoop::exec(ProcessEventsFlags flags) { Q_D(QEventLoop); auto threadData = d->threadData.loadRelaxed(); …. // remove posted quit events when entering a new event loop QCoreApplication *app = QCoreApplication::instance(); if (app && app->thread() == thread()) QCoreApplication::removePostedEvents(app, QEvent::Quit); while (!d->exit.loadAcquire()) processEvents(flags | WaitForMoreEvents | EventLoopExec); ref.exceptionCaught = false; return d->returnCode.loadRelaxed(); }
Ну, если между processEvents будут блокирующие вызовы, то мы все фризнем ui
Обсуждают сегодня