核心代码:
TcpThread *thread = new TcpThread(socketDescriptor);
thread->moveToThread(thread);
Qt中对于线程方面的理论网上有很多,看了一些并且结合自己使用的项目实践略作一下整理,希望大家能给个指点,不胜感激。其中不乏知识点,还请大家一起讨论学习。
本文章基于qt4.4以上版本,TCP通信。因为此版本对于qthread中的run进行了改进,支持object调用movetothread方法加入到线程中。
案例一、c/s工程项目中,有在线监测终端108套(可以理解为普通的客户端)需要接入到一个服务器上,同时工作。
提供解决方案:主进程中进行监听连接,监听到连接后开启线程进行服务器客户端的通信。每个客户端服务器都会分配一个线程与其通信,直到tcp连接断开,服务器捕获到信号后进行线程的回收。
实现:根据各位网络大牛给出的思想是设计一个object类调用movetothread到一个线程中。对于这样的方式给出一个简单的例子大家可以参考一下。
class Dummy:public QObject
{
Q_OBJECT
public:
Dummy(QObject* parent=0):QObject(parent) {}
public slots:
void emitsig()
{
emit sig();
}
signals:
void sig();
};
class Object:public QObject
{
Q_OBJECT
public:
Object(){}
public slots:
void slot()
{
qDebug()<<"from thread slot:" <<QThread::currentThreadId();
}
};
#include "main.moc"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug()<<"main thread:"<<QThread::currentThreadId();
QThread thread;
Object obj;
Dummy dummy;
obj.moveToThread(&thread);
QObject::connect(&dummy, SIGNAL(sig()), &obj, SLOT(slot()));
thread.start();
Dummy.emit sig();
return a.exec();
}
slot不在主线程中运行
main thread: 0x1a5c
from thread slot: 0x186c
上面就是一个简单的object加入到线程中的例子。如果开启多个线程,更重要的是我的object类还要存储客户端的一些信息,需要使用类的成员变量,也就是说108套设备我必须要使用不同的108个object指针变量,同时配带108个qthread指针变量。这样看,后面的资源回收以及内存开销都是一个麻烦事。我就有个想法:object就用qthread的子类mythread,然后把mythread 调用函数movetothread 放到 mythread自己中。代码如下:
TcpThread *thread = new TcpThread(socketDescriptor);
thread->moveToThread(thread);
//将线程的结束信号与deleteLater函数关联
connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));
//TCPSOCKET与主界面之间又多了一个thread
connect(thread,SIGNAL(DeviceConnected(QString,QString,QString)),this,SIGNAL(
incomingConnectionTableWidgetDo(QString,QString,QString)));
//断开连接时主界面修改
connect(thread,SIGNAL(DisConnectSocketToParent(int)),parent(),SLOT(
DisConnectSocketSlot(int)));
其他的一下连接我就不写了 其实主要就是前面的三行。connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));这行代码用于线程的回收。
这种使用方法,可以解决网上好多同仁的问题。例如:在线程中使用qtimer定时器的问题,以及在线程中自定义变量的问题。
这样的用法我稍微做了一下测试,没发现什么问题。但是对于取巧的用法总是感觉心里不踏实。还请各位同仁指点一二大家一起讨论一下QT中线程的问题。
归结点:其实如果不是这种一个客户端需要分配一个线程的情况。只是需要一个线程来执行一个简单的操作的话第一次贴代码的那些是最好的实现方法,但是要注意object中solt要加互斥锁qmutex。因为object不是线程安全的。