gpt4 book ai didi

带有 QtConcurrent::run 的 Qt QTcpSocket 需要单独线程中的事件循环

转载 作者:行者123 更新时间:2023-12-02 03:32:26 25 4
gpt4 key购买 nike

我在 Qt 中有一个 Web 服务器,它将读取一个非常大(~1Gb)的文件,并通过 QTcpSocket 将数据返回给请求者。该套接字由主服务器线程创建。我想使用 QtConcurrent 将此套接字移交给工作线程并将数据发送回那里。

// Using QtConcurrent
BackgroundConcurrent childThreadToReturnLotsOfData;
QFuture<void> futureObject = QtConcurrent::run(&childThreadToReturnLotsOfData, &BackgroundConcurrent::returnPartialLargeFile, resp , &fileToCheckExistence);

我的“returnPartialLargeFile”函数如下所示:

void BackgroundConcurrent::returnPartialLargeFile( QHttpResponse *resp , QFile *fileToCheckExistence  ) const
{

// We need an event loop for the QTCPSocket slots
QEventLoop loop;
//QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
// Execute our event loop
//loop.exec();

// To do this in another thread from the one created, you must
// move that socket to this thread, reparent and move
resp->m_connection->m_socket->setParent( 0 );
resp->m_connection->m_socket->moveToThread( QThread::currentThread() );

// Read in chunks until we have sent all data back to the requestor
QByteArray dataToWriteToSocket; // Store the data to send back
while ( dataReadFromFileInBytes > 0 ) {

// Read some Data into the byte array

// Write each chunk to the socket
resp->write(dataToWriteToSocket); // <----- Here is our data from the content of the file
resp->flushData(); // <----- Flush data to the socket

}

// End our response and close the connection
resp->end();
return;

}

我得到的错误是,如果我将“loop.exec()”行注释掉,我会收到以下错误:

ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread c2630. Receiver '' (of type 'QTcpServer') was created in thread 910a8", file kernel/qcoreapplication.cpp, line 501

如果我取消注释它,那么我的函数在 exec() 行处短路,并且永远不会向套接字写入数据,但我没有收到任何错误,我只是得到一个截断的响应,其中不包含来自的任何数据while 循环。

我正在重新设置套接字并将其移动到新线程,所以我希望我的问题仅与事件循环以及套接字信号和插槽有关。关于我在这里做错了什么有什么想法吗?我怎样才能让它发挥作用?如果出现信号/插槽问题,我需要在此处连接哪个?谢谢-

最佳答案

因此,您要做的就是在 while 循环中写入新线程中的响应。

在这种情况下,您不需要 moveToThread。

新线程将操作主线程拥有的对象是可以的。只要没有赛车。

如果两个线程都在套接字上运行,那么您需要一个互斥体。即使您将套接字移动到新线程,您也需要一个互斥体来防止数据争用(如果存在争用)。

Qt 有几个非常好的关于线程的文档。

阅读this让您了解何时需要 moveToThread,以及 this了解如何进行线程同步。以及所有these如果您想了解有关 Qt 中线程的更多信息,值得一读。

关于带有 QtConcurrent::run 的 Qt QTcpSocket 需要单独线程中的事件循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14839978/

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