что я могу использовать для замены сна и usleep в моем спокойном приложении?

Я импортирую часть существующего кода в мое спокойное приложение и заметил функцию сна там. Я вижу, что этот тип функции не имеет никакого места в программировании события. Что я должен сделать вместо этого?

ОБНОВЛЕНИЕ: После того, как думается и обратная связь я сказал бы, что ответ: назовите сон вне GUI основным потоком только и если необходимо ожидать в processEvents использования потока GUI () или цикл событий, это будет препятствовать тому, чтобы GUI заморозился.

10
задан yan bellavance 25 July 2011 в 18:02
поделиться

5 ответов

Совсем не обязательно разбивать события. Все, что мне нужно было сделать, это вызвать QApplication::processEvents(), где была sleep(), что предотвращает зависание графического интерфейса.

3
ответ дан 3 December 2019 в 14:43
поделиться

Я не рекомендую спать в системе, основанной на событиях, но если вы хотите ...
Вы можете использовать условие ожидания, таким образом, вы всегда можете прервать сна , если потребуется.

//...
QMutex dummy;
dummy.lock();
QWaitCondition waitCondition;
waitCondition.wait(&dummy, waitTime);
//...
9
ответ дан 3 December 2019 в 14:43
поделиться

Это не красиво, но я нашел это в Архивах списка рассылки Qt:

Метод сна QThread защищен, но вы можете выставить его так:

class SleeperThread : public QThread
{
public:
    static void msleep(unsigned long msecs)
    {
        QThread::msleep(msecs);
    }
};

Тогда просто вызывайте:

SleeperThread::msleep(1000);

из любого потока.

Однако, более элегантным решением было бы рефакторинг вашего кода для использования QTimer - это может потребовать сохранения состояния, чтобы вы знали, что делать, когда таймер отключается.

12
ответ дан 3 December 2019 в 14:43
поделиться

Причина, по которой сон является плохой идеей в событийном программировании, заключается в том, что событийное программирование фактически является формой на основе неактивной многозадачности. Вызовом "сна" вы предотвращаете активацию любого другого события и, следовательно, блокируете обработку потока.

В сценарии ответа на запрос для udp-пакетов, отправьте запрос и немедленно дождитесь ответа. Qt имеет хорошие API сокета, которые гарантируют, что сокет не блокируется во время ожидания события. Событие наступит, когда оно наступит. В вашем случае сигнал QSocket::readReady - это ваш друг.

Если вы хотите запланировать событие на какой-то момент времени в будущем, используйте QTimer. Это гарантирует, что другие события не будут заблокированы.

.
6
ответ дан 3 December 2019 в 14:43
поделиться

Я не знаю, как QT обрабатывают события внутренне, но на большинстве систем на самом низком уровне жизнь приложения идет так: код основного потока, по сути, представляет собой цикл (цикл сообщений ), в котором на каждой итерации приложение вызывает функцию, которая выдает ему новое сообщение; обычно эта функция блокируется, т.е. если сообщений нет, то функция не возвращается, и приложение останавливается.

Каждый раз, когда функция возвращается, у приложения появляется новое сообщение для обработки, которое обычно имеет некоторый получатель (окно, в которое отправляется), значение (код сообщения, например, указатель мыши был перемещен) и некоторые дополнительные данные (например мышь была перемещена в координаты 24, 12).

Теперь приложение должно обработать сообщение; операционная система или GUI-инструментарий обычно делают это под капотом, поэтому с помощью некоторой черной магии сообщение отправляется его получателю и выполняется корректный обработчик события. Когда обработчик событий возвращается, возвращается внутренняя функция, которая вызвала обработчик событий, возвращается та, которая вызвала его, и так далее, до тех пор, пока элемент управления не вернется в основной цикл, который теперь снова вызовет функцию получения магического сообщения, чтобы получить другое сообщение. Этот цикл продолжается до тех пор, пока приложение не завершит свою работу.

Теперь я написал все это, чтобы вы поняли, почему плохой сон в событийном GUI-приложении: если вы заметили, в то время как сообщение обрабатывается ни одно другое сообщение не может быть обработано , так как основной поток занят запуском обработчика событий, это, в конце концов, просто функция, вызываемая в цикле сообщений. Таким образом, если вы заставите обработчик событий спать, цикл сообщений также будет спать, что означает, что приложение в то же время не будет получать и обрабатывать любые другие сообщения, в том числе те, которые заставляют ваше окно перерисовывать, так что ваше приложение будет выглядеть "зависнуть" с точки зрения пользователя.

Короче говоря, не используйте сон, если вам не придется спать очень короткое время (несколько сотен миллисекунд максимум), в противном случае графический интерфейс станет невосприимчив к работе. У вас есть несколько вариантов, чтобы заменить сна : вы можете использовать таймер (QTimer), но это может потребовать от вас сделать много бухгалтерского учета между событиями таймера и другие. Популярной альтернативой является запуск отдельного рабочего потока: он будет просто обрабатывать UDP-связь, и, будучи отделенным от основного потока, не вызовет проблем со сном, когда это необходимо. Очевидно, что необходимо позаботиться о защите данных, совместно используемых потоками с мьютексами, и избегать условий гонки и всех других проблем, возникающих при многопоточности.

.
2
ответ дан 3 December 2019 в 14:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: