gpt4 book ai didi

c++ - 如何在不同的线程中执行 QTcpSocket?

转载 作者:可可西里 更新时间:2023-11-01 02:31:43 26 4
gpt4 key购买 nike

如何在不同的线程中执行 QTcpSocket 函数?

最佳答案

重要的是要注意在线程QTcpSocket方面你能做什么和不能做什么:

  • 可以在非主线程中使用它,但只能创建它的线程。

  • 不能从不同线程调用QTcpSocket 上的不同函数,例如在一个线程中读取,在另一个线程中写入。相反,您可以为每个 QTcpSocket 创建一个单独的线程,这可以防止它们耗尽时间和资源,而这些时间和资源可能会在主线程中绘制您的小部件。

IMO,将您的 IO(包括 QTcpSocket)放在主线程以外的线程中是最佳实践,对于任何高性能应用程序来说都是必须做的。我一直在非主线程中使用 QTcpSocket,使用以下习惯用法:


// Read data from a QTcpSocket in a thread. Assumes this is in some class.
m_thread = std::thread([this]
{
QEventLoop eventLoop;
QTcpSocket* socket = new QTcpSocket(&eventLoop);

socket->connectToHost("localhost", 9999);

// enqueue or process the data
QObject::connect(socket, &QTcpSocket::readyRead, &eventLoop, [socket]
{

m_concurrentQueue.push_back(socket->readAll());
});

// Quit the loop (and thread) if the socket it disconnected. You could also try
// reconnecting
QObject::connect(socket, &QTcpSocket::disconnected, &eventLoop, [&eventLoop]
{
eventLoop.quit();
});

eventLoop.exec();

delete socket;
});

其中 m_thread 是一些成员线程(基本上只是确保它的生命周期大于当前直接作用域),而 m_concurrentQueue 是一些线程安全队列,或者std 具有互斥保护的容器。

您还需要将一些信号(我通常称之为 joinAll)连接到事件循环退出函数,并从类析构函数中调用它。当使用线程中的事件循环习惯用法时,您始终必须小心确保您可以正确地销毁该类,否则您的程序将不会退出(或者在 Windows 上它将被终止,通常使用一些析构函数没有被调用,它最终成为一个静默错误)。

我通常还使用条件变量在创建线程后等待,直到事件循环开始。这不是必需的,但如果您将这些线程放在构造函数中,它可以帮助使程序流更有意义。

关于c++ - 如何在不同的线程中执行 QTcpSocket?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2698145/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com