LINUX.ORG.RU

deadlock при использовании QTcpSocket::readyRead()

 ,


0

1
#include "qt_socket_deadlock_test.h"
#include <QtWidgets/QApplication>
#include <QTcpSocket>
#include <QTcpServer>
#include <QDebug>
#include <QMessageBox>

#define REPRODUCE_ISSUE


int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	a.setQuitOnLastWindowClosed(false);
	qt_socket_deadlock_test test;
	test.show();
	QTcpServer server;
	QObject::connect(&server, &QTcpServer::newConnection, [&]() {

		QTcpSocket *socket = server.nextPendingConnection();
		QObject::connect(socket, &QTcpSocket::readyRead, [=]() {

			QByteArray data = socket->readAll();
			qDebug() << data;						
#ifdef REPRODUCE_ISSUE
			QMessageBox::information(0, QString("Data received"),
QString::fromUtf8(data), QMessageBox::StandardButton::Ok);
#else
			getchar();		
#endif
		});
	});
	server.listen(QHostAddress::LocalHost, 8888);		
	return a.exec();
}

Почему обработчик readyRead не вызывается повторно, если данные были получены пока QMessageBox не был закрыт, но вызывается, если использовать getchar?

В обоих случаях блокируется поток UI, но событие получения данных теряется только при использовании QMessageBox.


Ответ на: комментарий от anonymous

Пример вымышленный - изначально хотел посмотреть, как себя будет вести QTcpSocket, если данные поступят во время выполнения readyRead.

QMessageBox здесь используется просто как временная пауза, чтобы можно было отправить данные приложению и посмотреть, вызовется ли readyRead повторно.

Заменил его на такую имитацию паузы:

QEventLoop sillyBlockingOperation;
QTimer t;
t.setInterval(10000);
t.setSingleShot(true);
QObject::connect(&t, &QTimer::timeout, &sillyBlockingOperation, &QEventLoop::quit);
t.start();
sillyBlockingOperation.exec();

Видно что сообщения обрабатываются - по крайней мере, форму можно перемещать и кликать по виджетам на ней, но событие поступивших данных все равно теряется.

H3 ()
Ответ на: комментарий от H3

Заменил его на такую имитацию паузы:

есть более нормальные фокусы остановки потока.

MikeDM ★★★★★ ()
Ответ на: комментарий от MikeDM

getchar тоже блокирует, пока не получен ввод от пользователя, однако вышеописанной проблемы не вызывает.

QEventLoop не блокирует обработку сообщений, но readyRead не вызывается повторно.

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

H3 ()
Ответ на: комментарий от H3

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

MikeDM ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.