Требует ли QThread :: sleep () выполнения цикла событий? - PullRequest
1 голос
/ 03 апреля 2010

У меня есть простая клиент-серверная программа, написанная на Qt, где процессы взаимодействуют с использованием MPI. Основной дизайн, который я пытаюсь реализовать, следующий:

  1. Первый процесс («сервер») запускает графический интерфейс пользователя (производный от QMainWindow), который прослушивает сообщения от клиентов (с использованием повторного запуска QTimer s и асинхронных вызовов MPI), обновляет Графический интерфейс в зависимости от того, какие сообщения он получает, и отправляет ответ на каждое сообщение.

  2. Каждый другой процесс («клиенты») выполняется в бесконечном цикле, и все, что они должны сделать, - это отправить сообщение процессу сервера, получить ответ, ненадолго перейти в спящий режим и затем разбудить и повтори. Каждый процесс создает отдельный объект, полученный из QThread, и вызывает его метод start(). Метод run() этих классов выглядит следующим образом:

из foo.cpp:

void Foo::run()
{
    while (true)
    {
        // Send message to the first process
        // Wait for a reply
        // Do uninteresting stuff with the reply
        sleep(3);    // also tried QThread::sleep(3)
    }
}

В коде клиента нигде нет вызова exec(), поэтому цикл событий не должен начинаться.

Проблема в том, что клиенты никогда не выходят из спящего режима (если я окружаю вызов sleep() двумя записями в файл журнала, выполняется только первая, управление никогда не достигает второй). Это потому, что я не запустил цикл событий? И если да, то как проще всего добиться желаемой функциональности?

Ответы [ 2 ]

0 голосов
/ 23 июня 2015

Ответ на этот вопрос в одну строку - сон и цикл обработки событий не связаны. Sleep переводит вызывающий поток в спящий режим независимо от того, вызывается ли он из переопределенной функции run() потока или любой другой функции в этом отношении. Это не имеет значения, и нет спасения. Фактически, если exec() вызывается где-то в run() (что является реализацией QThread по умолчанию), элемент управления не вернется к вызывающей стороне.

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

Возможно, когда был задан этот вопрос, QThread :: sleep () была закрытой функцией. Теперь с Qt 5 sleep или msleep или даже usleep являются открытыми статическими функциями.

0 голосов
/ 03 апреля 2010

Некоторым классам в коде клиента может потребоваться запуск цикла обработки событий. Зачем использовать QThreads для клиентов, если у вас нет цикла обработки событий для клиентов, и вы уже используете MPI?

...