Почему выполняется новый сигнал для socket :: readyRead (), даже если его предыдущий слот все еще обрабатывается?

Согласно следующему сообщению излучаемый сигнал обслуживается только после завершения текущего исполняемого интервала.
Подождите, пока слот завершит выполнение с Qt

У меня есть клиент-серверное приложение связи на основе ssl-сокета, который является однопоточным.

connect(socket, &QSslSocket::readyRead, [&]() { myObject.Read(); });

клиент & Сервер отправляет друг другу несколько пользовательских сообщений. Всякий раз, когда сообщение отправлено или получено одним из них, они отправляют ACK байт (00).
В большинстве случаев я замечаю, что когда Read() между исполнением, следующий readyRead() подан! Я положил отладочные утверждения в начале & конец чего-либо myObject->Read(), Они подтверждают, что начало отладки вызывается снова & снова. То же самое наблюдается с точками останова.

Когда получено слишком много данных, рекурсивный кадр стека создается из слишком большого количества данных. Read()s. Это либо замедляет работу графического интерфейса приложения, либо вылетает.
Обычно эта рекурсия происходит, когда клиент пытается отправить ACK как часть myObject->Read(), В течение этого времени readyRead() случайно сигнализируется & также обслуживается. Однако слот предыдущего сигнала все еще обрабатывался.

Вопросы:

  • Возможно ли для инфраструктуры Qt обрабатывать сигнал между слотами, когда слот все еще находится в середине пути (однопотоковый)?
  • Как исправить этот сценарий для конкретного сокета?

Заметка:
— По умолчанию для отдельных потоков Qt::ConnectionType является DirectConnection, Я пробовал с QueuedConnection как хорошо, но результат тот же.
myObject.Read() довольно сложный и имеет много других вызовов функций. Если это вызывает проблемы, то дайте мне знать, что я должен искать. Будет непрактично писать реальный код этого.

5

Решение

Рекурсивные вызовы readyRead() происходило из-за того, что цикл событий освобождается между ними. Следующие функции вызывали освобождение цикла событий:

  1. QCoreApplication::processEvents()
  2. SslSocket::flush()

1-й понятен, так как он предназначен для этого. Но 2-й flush() было полной неожиданностью. это документация не утверждает так. По крайней мере, в моей отладке это показывало, что всякий раз, когда flush() вызывается, последующий readyRead() вызывается и обслуживается. Смотрите это и в Qn.

processEvent() предназначался для того, чтобы сделать GUI более отзывчивым во время высокой загрузки данных. Но, похоже, нам нужно сделать еще один выбор для того же.

2

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

Других решений пока нет …

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