Как сделать так, чтобы слот, связанный с QTimer :: timeout, мог быть прерван любым другим сигнальным процессором (с более высоким приоритетом), а затем возобновлен? - PullRequest
0 голосов
/ 08 мая 2019

Чтобы упростить вопрос, скажем, у меня есть QTimer, который будет вызывать событие тайм-аута каждые 3000 мс.

QTimer timer;

QObject::connect(&timer, &QTimer::timeout, [&](){
    // do sth(rely on a public data structure)
}); 

timer.start(3000);

Операция внутри лямбды, подключенной к событию timeout, полагаетсяв публичной структуре данных.

И приложение удерживает QUdpSocket и соединяет сигнал readyRead с функцией слота.

QUdpSocket socket;
socket.bind(45454, QUdpSocket::ReuseAddressHint);

QObject::connect(&socket, &QUdpSocket::readyRead, [&](){
    //manipulate the public data structure
}

Как видите, лямбда подключенак сигналу readyRead манипулировать структурой общедоступных данных, на которую опирается первая лямбда.

Поэтому мой вопрос: я хочу, чтобы функция, подключенная к сигналу readyRead, имела самый высокий «приоритет», то естьдаже в цикле обработки событий Qt теперь работает со слотом timeout, его можно прервать и сразу запустить слот readyRead, а затем, после его завершения, возобновить функцию слота timeout.Есть ли способ сделать это?

(Моя домашняя работа состоит в том, чтобы смоделировать проблему открытого / скрытого узла IEEE802.11, она требует, чтобы я постоянно прослушивал канал до / во время отправки пакета.)

(явно вызов QCoreApplication::processEvent поможет?)

1 Ответ

0 голосов
/ 09 мая 2019

Я не знаком с проблемой открытого / скрытого узла IEEE802.11, однако я не думаю, что вы можете «прервать» ваш код в процессе описания.

Один из возможных способов справиться с этим - запустить код для readyRead и интервалов времени ожидания в разных потоках, а затем использовать какой-то механизм синхронизации (приходит на ум QMutex) для доступа к общедоступным данным (и получения их состояния). .

т.е.

  1. добавить какой-то уникальный идентификатор для определения текущего статуса public_data

  2. timeout_slot получит блокировку, прочитает открытые данные в локальной копии и снимет блокировку, затем продолжит манипулировать локальной структурой и, наконец, перед освобождением снова получит блокировку и проверит, что uniqueid не был изменен, если так что посвятите свою работу, иначе вам придется начинать все сначала.

  3. readyRead_slot получит блокировку, обновит uniqueid и продолжит работу

...