QT 线程池 + TCP 小试

跑马溜溜的山上 2012-08-11 06:57:39
*免分资源链接http://download.csdn.net/detail/goldenhawking/4492378
引用:http://blog.csdn.net/goldenhawking/article/details/7854413
很久以前做过ACE + MFC/QT 的中轻量级线程池应用,大概就是利用线程池执行客户机上的运算需求,将结果返回。ACE是跨平台重量级的通信中间件,与常见的应用程序框架需要精心契合,才能不出问题。最近想到既然QT框架本身就已经具有各类功能,何不玩一玩呢吐舌头,那就开搞!这个实验的代码可以从我的资源内下载。

第一步打算实现的模式,我们需要一个设置为CPU核心数的线程池,这个线程池可以异步接受N个数据生产者传入的数据,均衡的分配处理任务,处理后的数据返回给某1个或者几个消费者。有两种均衡方法。一种是生产者粒度的均衡。同一个生产者的各批数据FIFO顺序不被打破,这需要判断,当处理线程队列中还有该生产者的数据时,不改变当前处理线程。第二种是数据粒度的并行,某个生产者传来的数据被分配到不同的线程,不保证后到的数据后被处理(也可能先到的处理的慢,后到的快)。

这种异步队列机制如果在MFC、WinAPI中,需要手工使用 Mutex 同步队列,更可恶的是分配的数据对象的生存期非常微妙,一不小心就会出红叉叉。QT首先为我们提供了信号和槽的机制,且该机制原生支持跨线程。假设我们在16核心服务器上,则使用 15个 QThread对象管理15组工作线程(留一个给主界面)。但是,如果仔细看了QT的文档,就会发现QThread的信号事件循环默认是在创建者中(很多时候就是主线程!),所以,要想让槽在子线程运行,一般是派生一个QObject的类,并把对象MoveToThread到某个QThread管理的线程上去。这样,信号和槽就是全异步FIFO了。其次,QT提供了引用计数的QByteArray封装,这个东西在参数传递的时候,速度很快,很少出现memcpy,生存期也特别容易控制。虽然C++11里有 shared_ptr<T>,但是那个东西还是需要在一开始new 一个int8型的存储区,很讨厌。

有了线程池,我们下一步就利用 QTcpServer 搭建一个服务器,接受客户端的连接,并把数据发送到线程池上。由于 QTcpServer 资料太多了,这里不在赘述。唯一值得注意的是,当客户端退出时,如果线程池队列中还有该客户的信息,这个信息还会被处理,只是无法再发送回去而已。其实,还可实现成客户端退出,就发一个信号到线程池,删除自己的所有任务。这个也很简单,但之所以没有做,因为这些数据的处理结果可能还会被其他消费者(而非生产者自己)使用,最典型的例子是从工业传感器上采集的数据,其生成的图像需要存储到设备中去。

QTcpSocket的 Write 方法默认是支持大体积数据的,即使一次发了500MB的数据,只要硬件资源可以承受,调用也会成功并立刻返回。接受者会以一定的载荷大小不停的触发readyRead,直到发送全部成功。但是,为了能够观察到并控制收发队列中的数据包的大小、体积,我们在外层实现了一个发送队列,每次以 payLoad为大小发送数据包。这是从MFC中带来的习惯,很难说好坏。
有了TCP、线程池,我们就可以把他们连接起来。使用最简单的 QMainWindow吧,设计个UI,而后,创建我们的线程池、Service,并把TcpService 的数据接收信号与线程池的数据处理信号连接起来。

为了模拟处理任务,我们简单的设计一个转换大小写字符的函数作为处理过程的模拟,这样有利于在超级终端调试、模拟。为了检验线程池,可以通过加入 _sleep 模拟耗时的工作。


...全文
1070 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
stelleroid 2012-11-11
  • 打赏
  • 举报
回复
昨天看了没评论么,, 好 补上,支持楼主。
LittleGrayEagle 2012-09-02
  • 打赏
  • 举报
回复
恩!很不错,你这个家伙越来越牛了啊!老大让你工作,你却偷偷看书,让我们这些人怎么混啊!
  • 打赏
  • 举报
回复
如果发很大的数据,因为数据包的接收是以一定单位字节为一批的,所以,还需要手工控制组包。
shn521 2012-08-22
  • 打赏
  • 举报
回复
回去下载研究下
  • 打赏
  • 举报
回复
其实,Windows 下命令行编译更简单
具体方法。

1、打开QT的命令行

2、编译客户端、服务器


3、可以在Debug, Release里看到东东了

4、如果不能运行,设置系统路径
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

LZ用的VC2010?
[/Quote]
VC2010也可以,Ubuntu QT 也可以,Windows 下的命令行qmake也可以,都试过啦
  • 打赏
  • 举报
回复
LZ用的VC2010?
xiebin133 2012-08-13
  • 打赏
  • 举报
回复
好贴,顶一下。顺便拿一份源码看看。
AAA20090987 2012-08-13
  • 打赏
  • 举报
回复
好帖,
不要有点深,MARK一下慢慢看
绿领巾童鞋 2012-08-13
  • 打赏
  • 举报
回复
好东西~
谢谢分享
wyk_08 2012-08-12
  • 打赏
  • 举报
回复
特來學習一下...我初學有很多疑問呢..先謝謝了..

16,201

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧