C++ 多线程框架(3):消息队列

之前,多线程一些基本的东西,包括线程创建,互斥锁,信号量,我们都已经封装,下面来看看消息队列

我们尽量少用系统自带的消息队列(比如Linux的sys/msgqueue),那样移植性不是很强,我们希望的消息队列,在消息打包和提取都是用的标准的C++数据结构,当然,你也可以用链表或者是FIFO,那样得先写个链表或者FIFO出来。

我比较懒,直接用的C++的STL的deque,即双端口队列,这样可靠性有保证,当然,速度可能没有自己写的链表快,但是没关系,使用双端口队列还可以根据你自己的需要将数据插入到队列头或者队列尾,这样在消息有优先级的情况下还是有用的。

消息队列的核心作用其实很简单,一个或多个线程往一个队列后面堆数据,另外的一个线程从队列前面取数据处理,基本操作也只有两个,一个发,一个收,所以,我们定义消息队列基类为:

然后记得在COperratingSystemFactory里加上创建消息队列的方法:

最后,从CMsgQueue继承一个CLinuxMsgQueue,然后把recvMsg和sendMsg实现吧,实现的时候注意一下。

单纯的操作双端口FIFO不行,我们希望是接收消息的时候如果没有消息,线程阻塞在那里等待消息直到有消息到来才接着运行,所以,接收消息的时候我们用了信号量,阻塞在信号量那里,发送消息的时候操作完队列,发送一个信号量出去。

其次,对于队列的操作,我们希望是原子性的,不然一个正在收一个正在发就乱了,所以操作队列的时候我们用互斥锁来锁一下,保证基本的原子性。

对应到具体的程序就是

1.为每个消息队列申请一个锁,一个信号量

接收消息的时候:

发送的时候也是类似的方式进行,这样,一个最简单消息队列就完成了。如果我们要使用消息队列的话,很简单,在main.cpp中

当要在mainloop中发送消息的时候,只需要调用

github地址:
https://github.com/wyh267/Cplusplus_Thread_Lib

写在后面的话:

当然,这个代码还非常不完整,整个代码量也没有多少行,在这里,我只是提供一个代码框架的方法,作为一个demo给大家参考,如果真的需要实际使用还有很多很多地方需要修改的,github上我的代码也不能在生产软件中实际使用,在实际的项目中,我也实现了一个没有任何第三方的线程库,比这个复杂多了,还包括事件处理,等待超时,消息广播,消息订阅等模块,而且能运行在linux,ecos等多个平台上,基本做到平台无关了,但由于各种原因我也没办法将代码都公布出来,这里所说的这个框架只是项目中线程库提取出来的非常少的一部分,同样,也只是提供一种编程的设计思想,后面的东西希望大家各自有各自的发掘和完善,也许你看了以后,会提出更加强大和简洁的框架。

另外,github上的代码我会继续完善,将其他模块陆续加上,如果大家感兴趣也可以跟我一起来完善,我尽量不使用之前实现过的线程库的代码,避免不必要的麻烦。

打赏支持我写出更多好文章,谢谢!

打赏作者

打赏支持我写出更多好文章,谢谢!

2 4 收藏 4 评论

关于作者:吳YH堅

一个老程序员,做过内核,做过驱动,做过嵌入式,目前在做搜索,推荐,广告~~ 个人主页 · 我的文章 · 16 ·  

相关文章

可能感兴趣的话题



直接登录
最新评论
  • 诸葛不亮 Qt/C++程序员 2016/11/06

    这里有个问题——std::deque并不保证thread safefy

    实际应该使用的,是采用atomic操作实现的无锁队列,比如

    http://coolshell.cn/articles/8239.html

    • 诸葛不亮 Qt/C++程序员 2016/11/06

      楼主是使用互斥锁啊……这个性能就要低许多了,队列操作并不复杂,用原子操作就可以实现线程安全了,性能差别可以看这个帖子

      http://blog.jobbole.com/107471/

       

    • 吳YH堅   01/18

      哈,谢谢指出来,这篇文章实际上应该是07,08年左右的。那时候确实对C++的理解还不够。现在看来有很多地方不好。哈哈。。

      • 诸葛不亮 Qt/C++程序员 01/18

        而且用互斥锁的地方,很多时候可以换成用读写锁,性能会更好。然后就是根据实际的场景,判断下该用互斥锁/读写锁,还是用自旋锁了,这两者各有优劣。而atomic大多是用于自旋锁的

         

跳到底部
返回顶部