找回密码
 FreeOZ用户注册
查看: 5510|回复: 7
打印 上一主题 下一主题

[论坛技术] Qt的线程和 signal-slot

[复制链接]
跳转到指定楼层
1#
发表于 11-7-2010 23:00:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?FreeOZ用户注册

x
再问coredump或者QT高手们一个问题。QT里用线程,主线程是GUI,次线程是工作线程,如果次线程里也用消息循环(exec),即,主/次间用signal-slot通讯来实现同步,在这种情况下,
1.主线程会被次线程block吗?
2.如果在单cpu里会被block吗,如果次线程里不断循环,低层会自动分配时间片给主线程吗?
3.这种方法和直接调用次线程中的方法,用mutex之类的来实现类似的循环,效率差别大吗?记得QT里讲过signal-slot只是多几个函数调用的差别。
呵呵,问的不太清楚,主要就是想问一下,主次线程中怎样通讯比较有效。
谢谢阿。
回复  

使用道具 举报

2#
发表于 12-7-2010 10:59:46 | 只看该作者
QThread 现在默认状态下就是有一个消息循环的,而且鼓励使用线程独立的消息循环

1.主线程会被次线程block吗?
   不会,QObject::connectd的最后一个参数(http://doc.qt.nokia.com/4.6/qt.html#ConnectionType-enum) 默认使用Qt::AutoConnection, 在多线程环境下,会自动选择Qt::QueuedConnection方式,除非强制使用Qt::BlockingQueuedConnection或者Qt::DirectConnection, 否则线程不会block.
2.如果在单cpu里会被block吗,如果次线程里不断循环,低层会自动分配时间片给主线程吗?
   线程和CPU个数没有关系,当然CPU多了,运行会更加流程,线程的资源分配(时间片)是由操作系统管理的,在各个系统上都是如此
3.这种方法和直接调用次线程中的方法,用mutex之类的来实现类似的循环,效率差别大吗?
   执行效率上很难讲,但是mutex肯定是带来了开发效率的降低,你得小心翼翼地处理好各种临界资源的锁问题
4. 记得QT里讲过signal-slot只是多几个函数调用的差别
   是的,signal-slot的这种轻微的效率损失在绝大多数情况下不是问题,除非过度使用,这一般是设计上的错误导致的

分享两篇文章,讲QThread和Qt的signal-slot的:
1篇是qt labs的博客上一篇 You are doing it wrong...(http://labs.trolltech.com/blogs/2010/06/17/youre-doing-it-wrong/), 这篇文章很有意思,其实很多人不知道原来QThread还可以这样用。
另外一篇是关于怎么利用Qt的signal-slot机制和QThread进行完全的lock free编程(http://thesmithfam.org/blog/2009 ... ti-threading-in-qt/)
回复  

使用道具 举报

3#
 楼主| 发表于 12-7-2010 13:13:30 | 只看该作者
多谢多谢,再学习去。
之所以问,是因为,我做了一个下载googlemap的程序,开始下载线程后,GUI就不动了,直到下载结束。虽然操作系统会分配时间,但是如果下载线程循环,而且优先级相同的话,是不是还是有影响?
回复  

使用道具 举报

4#
发表于 12-7-2010 13:14:27 | 只看该作者
原帖由 GPS 于 12-7-2010 12:13 发表
多谢多谢,再学习去。
之所以问,是因为,我做了一个下载googlemap的程序,开始下载线程后,GUI就不动了,直到下载结束。虽然操作系统会分配时间,但是如果下载线程循环,而且优先级相同的话,是不是还是有影响?
不应该。
回复  

使用道具 举报

5#
 楼主| 发表于 12-7-2010 13:40:27 | 只看该作者
原帖由 coredump 于 12-7-2010 12:14 发表
不应该。

我再看看哪里出问题了。
刚看了你上面的两个链接,真是切中要害阿,呵呵,一直就在琢磨这个一段时间了。
总结一下理解,看看对不对。
第一篇里,QThread里默认的run()已经启动了消息循环exec(). 当需要新线程时,应该,直接生成QThread, start()。至于功能,应该放在另外的类里,在调用start前设置好signal-slot,再moveToThread到 QThread中。 不用sunbclass QThread。
我一直或者重新实现run(),在run()里生成所有object, signal-slot, 或者如文中所说的QThread.moveToThread(QThread). 这两种都有不少问题,破坏OO的概念。
很清楚。

评分

参与人数 1威望 +30 收起 理由
coredump + 30 谢谢分享!

查看全部评分

回复  

使用道具 举报

6#
 楼主| 发表于 12-7-2010 13:50:35 | 只看该作者
第二篇里讲了用线程间的signal-slot来同步,正好回答了之前的疑问,不过他使用qthread的方法恰恰违背了第一篇的思想。
回复  

使用道具 举报

7#
发表于 12-7-2010 13:50:40 | 只看该作者
原帖由 GPS 于 12-7-2010 12:40 发表

我再看看哪里出问题了。
刚看了你上面的两个链接,真是切中要害阿,呵呵,一直就在琢磨这个一段时间了。
总结一下理解,看看对不对。
第一篇里,QThread里默认的run()已经启动了消息循环exec(). 当需要新线程时 ...

另一种方式也不错,有些情况下必须subclass QThread, 错的不是是否subclass,错在:subclassing QThread, adding signal and slot code to that subclass, and then calling moveToThread(this);
To set the record straight: I’m not saying sub-classing QThread is wrong. This is also how Java does it (sort of), and many people have been doing this with Qt for a long time.
What I’m saying is “wrong” is subclassing QThread, adding signal and slot code to that subclass, and then calling moveToThread(this); in the constructor of that subclass. This causes people lots of confusion from my experience and observation on the #qt channel and the qt-interest mailing list.
And yes, the current docs are still a bit lacking, something that I am fully aware of (and take responsibility for). I’m planning on sitting down and fleshing them out, showing both ways of using QThread (with and without subclassing).




在Qt的编程模型里,thread和signal-slot都是实现异步编程的手段,signal-slot的背后是消息循环,而每个thread都是一个独立的消息循环,在早期版本,qt线程间无法进行signal-slot消息传递,这就导致了各个消息循环都是互相独立的loop, 通讯的唯一方式只剩下global state+ mutex lock。在4.x 之后,signal-slot已经能够和thread融洽相处了。

这样,理想的QT编程模型就变成了独立的一个个任务,各自使用自己的thread和thread内部消息循环,在需要互相通讯的时候,使用signal-slot, 这些signal和slot就是明确定义的消息接口,除此之外,最好不共享其它状态。Qt程序员有点像转盘子的杂技演员,每个盘子都独自转动,整个系统由很多旋转的盘子组成,这些盘子可以共享杂技演员一个手,也可以是另一只手甚至不同的杂技演员来控制(多CPU)。

[ 本帖最后由 coredump 于 12-7-2010 12:55 编辑 ]
回复  

使用道具 举报

8#
 楼主| 发表于 16-7-2010 22:42:45 | 只看该作者
原帖由 coredump 于 12-7-2010 12:14 发表
不应该。

搞清楚了,忘了QThread.moveToThread(this)了,结果是下载线程对象里的slots也在主线程了调用了。多谢指点。
回复  

使用道具 举报

您需要登录后才可以回帖 登录 | FreeOZ用户注册

本版积分规则

小黑屋|手机版|Archiver|FreeOZ论坛

GMT+11, 27-12-2024 22:36 , Processed in 0.042646 second(s), 27 queries , Gzip On, Redis On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表