C++ 线程间通信 标准库与boost

关键词:C++ 线程间通信 消息中间件 C++11标准库 boost

引子

        为什么使用多线程?线程间为何需要通信?

        通常认为,存在多个任务,则需要创建多线程。这种说法太过于笼统,很难让人理解到精要,有一种豁然开朗的感觉。又或者说,对于更高级别的并发,处理器以及计算机特性没有更为是深入的理解。或者说,没有说明多线程的关键作用。

        那么,引入一个多线程中的重要概念:多线程用来平衡不同任务负载。

        计算机的处理器的每一项工作所占用的资源是不同的。比如搬运数据,使用DMA操作,可以无需占用处理器。比如中断资源和正常任务运行,中断往往是珍贵的、稀缺的,不能在中断里处理复杂任务,以免影响下一次的中断。而非紧急响应的任务,则可以移步到普通任务去执行。

效率增加    

        我这里引用一个例子,以工厂加工一个产品为例子。加工一个产品需要两道工序。假设工序A需要2小时加工一件,工序B需要5小时加工一件。

        如果有一个工人(2个核心),可以同时照顾A与B,那么生产一件需要多久?答案是第一件需要7小时,随后的每一件需要5个小时,这取决于较慢的那个工序。也就是取决于短板。

        实际上一个工人(这里指电脑的处理器,通常是多个核心的),可以同时干更多的活。假设这个工人可以兼顾7个流水线(7个核心)。2个工序A流水线,5个工序B流水线。这样是不是产能最大?这样生产一个需要多久,假设工序A生产了很多件作为起始。那么现在开始计算的话,流水线B平均每小时消耗1件,流水线A平均每小时生产1件。那么该产线的效率是1小时每件

       实际计算,核心数由2个增加到了7个,处理器是原来的3.5倍性能提升,效率却是原来的5倍的提升。这就是关键。

为什么?

       实际上,我们让需要时间更长的工序不再成为短板,生产者效率等于消费者效率,以便最大化效益。这就是多线程的作用,平衡不同任务间的负载。

生产者1        生产者2        生产者3        生产者4        ……        生产者n
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
                         生产者放入 →         仓库         →消费者取出
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
消费者1        消费者2        消费者3        消费者4        ……        消费者n

临时概念

        产物(临时概念)

        每道工序后的成品,具体指经计算机加工后的信息。

        生产者

        通俗释义:上一道工序或者任务或者线程。产出一些产物(加工完的信息)。

        消费者

        通俗释义:下一道工序或者任务或者线程,消费一些产物(待加工的信息)。

        邮箱

        通俗释义:工序间、任务间、线程间通信的工具,邮箱传递邮件。通常是比较小的产物(加工后的信息的地址)。

        消息队列

        通俗释义: 一个放产物的空间(仓库),比邮箱大一些的产物(加工后的信息)。

        环形缓冲区(临时概念)

        通俗释义:还是放产物的空间(仓库),不过是环形的,不会溢出,满了就丢一些。

        存储仓库(临时概念)

         通俗释义:还是放产物的空间(仓库)。

        消息中间件

        通俗释义:放产物的,也就是线程间通信工具,以上放产物的这些大大小小仓库的总称。

核心概念

        通过以上场景,剔除临时概念用于理解。保留关键部分。

        线程范畴

        生产线程,消费线程。

        消息中间件

        邮箱,消息队列。

场景

        单片机

        数据的中断接收与数据处理操作。       

        TCP

        数据的接收与处理操作。​​​​​​​

        分布式架构

        分布式高并发架构提升响应。

标准库

       线程间同步与线程间通信。

        c++11 标准库提供的线程间工具有三个。信号量,锁,条件变量。

BOOST

        *(待补充)

        

        

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++ 中线程间通信可以使用互斥锁(mutex)、条件变量(condition variable)等机制来实现。下面是一个简单的例子: ```c++ #include <iostream> #include <thread> #include <mutex> #include <condition_variable> std::mutex mtx; std::condition_variable cv; bool ready = false; void funcA() { // 这里做一些耗时的操作 std::this_thread::sleep_for(std::chrono::seconds(1)); // 加锁 std::unique_lock<std::mutex> lck(mtx); // 设置 ready 标志位为 true ready = true; // 通知等待的线程 cv.notify_all(); } void funcB() { // 加锁 std::unique_lock<std::mutex> lck(mtx); // 等待 ready 标志位为 true cv.wait(lck, []{ return ready; }); // ready 标志位为 true 时执行下面的代码 std::cout << "Hello, world!" << std::endl; } int main() { // 创建两个线程 std::thread t1(funcA); std::thread t2(funcB); // 等待两个线程结束 t1.join(); t2.join(); return 0; } ``` 其中,`funcA` 线程会在执行完一些耗时的操作后设置 `ready` 标志位为 true,并通知等待的线程。`funcB` 线程会等待 `ready` 标志位为 true 后输出一条消息。 在这个例子中,我们使用了一个互斥锁和一个条件变量来实现线程间通信。`std::unique_lock` 是一个 RAII 封装的互斥锁,它可以自动释放锁。`std::condition_variable` 是一个条件变量,它可以在等待时自动释放锁,并在通知时重新获取锁。在等待时,`cv.wait(lck, predicate)` 会释放锁并等待条件变量被通知。`predicate` 是一个可调用对象,用于判断条件是否满足。在通知时,`cv.notify_all()` 会通知所有等待的线程,并重新获取锁。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值