注:此文不涉及Qt线程使用的具体代码例子,如果是怎么使用Qt线程,见下面链接。
现在写一个项目并行和多线程几乎是必用的。在Qt中最多的是用QThread,只是QThread有两种用法,继承与QObject::moveToThread函数。在群里有人郁闷Qthread的用法,此文写下个人简单的见解。
首先简单说下QThread的这两种用法:
1.继承QThread使用方法:
继承QThread类,实现其run()函数,那么run函数里的都是在新线程调用。
2.QObject::moveToThread:
一个类继承QObject,然后使用QObject::moveToThread(QThread *)函数,把这个类移动到新的线程中去,然后与主线程全部通过信号槽Qt::QueuedConnection或者Qt::BlockingQueuedConnection(阻塞调用线程,槽函数执行完毕才继续执行)进行信号槽链接进行线程间通讯,那么信号触发的槽是在新的线程执行的,同样新线程的信号链接的主线程的槽,也是在主线程执行的。但是直接调用函数和Qt::DirectConnection链接信号槽的槽函数,是会在直接调用的函数和信号发出的线程中执行的。对于Qt::AutoConnection(Qt默认的链接方式)链接的信号槽,如果在一个线程就是Qt::DirectConnection,不在一个线程就是Qt::QueuedConnection。
注:movetothread底层是依赖Qt时间循环实现的(QCoreApplication::postEvent),所以使用movetothread必须是在开启Qt事件循环的程序中,就是main函数中调用QCoreApplication::exec的程序。
技术都是为业务服务的,同样多线程我们使用也是为了解决场景问题的,如果你只是为了多线程而多线程,那么本文对您已经结束了。
首先假设都是在Qt程序中(即基于Qt事件循环的程序中)。然后按照个人使用过场景来说下个人以为的Qt线程的使用方式。
1.耗时的一次计算,I/O或者初始化:
不建议使用QThread,建议使用:QRunnable和QThreadPool结合使用或者直接,QtConcurrent::run
2.周期性的耗时计算或I/O:
使用继承QObject和moveToThread函数的方式,封装到类中,然后后台线程启动驻留,然后信号槽传送计算参数和接收计算的数据。
3.程序线程分模块,例如网络和数据库单独在一个线程或者分别的线程设计:
使用继承Qobject和moveToThread函数的方式,封装到类中,然后后台线程启动驻留,然后信号槽传送操作命令和取回结果。(注QWidget的UI操作只能在主线程的)。
4.多个任务执行者,分别的执行,一个调度者:
每个封装一个类,然后执行者和调度者分线程,数个或者单个执行者一个线程,通过信号槽与调度者交互,用moveToThread方式分线程。
5.程序中引用其他库,其他库且有独立的事件循环:
用继承QThread的方式,在run中启用其他库的事件循环,需要与主线程交互的部分采用自定义事件和QCoreApplication::postEvent方式通讯。(下面链接:QAsioTcpSocket)。
一般的能用到线程的场景,我也就使用过和想到这么多。其中:
周期性的小任务(几乎不耗时的)使用定时器,用到线程的。
Qt中的网络访问:Qt的网络接口都是默认异步的,异步就没有等待只说,也就用不到线程,所以不是为了划分模块不建议单独线程的。当然你要强制全同步访问另算(不感觉同步优势,自定义状态机就解决异步调度的问题了啊?)。
附:
1.Qt线程使用的教程:
2.我的项目中使用Qthread的例子:
QTcpServer多线程实现 这篇文章提到的QthreadTcpserver
QAsioTcpSocket 目的是把asio封装一个与Qt结合的版本,替代低效QTcpServer。
谢谢分享http://bbs.ipmhw.com/
偶然经过贵站,盼望回访,xrpmoon
多谢来访、、
我们身边重要的人越来越少,而留在身边的人越来越重要。
[粉红丝带]
有两个人,其中一个脸上崎岖不平,另一个人对他说:你知道吗,苍蝇不敢落在你的脸上哎!
他很纳闷,问:为什么呢?
呵呵,怕崴脚。
如果这样说,苍蝇也不敢落在你的脸上啊!
哦?
因为你的脸太滑了!它怕匹叉! http://url.cn/XfB45g
不错。感谢楼主。宋世鹏宇宙信息网