并发编程 - Boost Thread

c++并发编程 - Boost Thread 0x00 摘要在分析比特币源码时,最开始就简单学习了一些boost thread的简单用法和最基本的互斥锁,但看到后面发现还用到了更深层次的并发编程知识,于是又回来完整的学习一下,这里做个学习的总结。本文的内容主要包括线程组(Thread group)以及各种互斥锁(lock_guard, unique_lock)以及更高级一点的condition variable。 阅读详情
c++并发编程 - Boost Thread

0x00 摘要

在分析比特币源码时,最开始就简单学习了一些boost thread的简单用法和最基本的互斥锁,但看到后面发现还用到了更深层次的并发编程知识,于是又回来完整的学习一下,这里做个学习的总结。本文的内容主要包括线程组(Thread group)以及各种互斥锁(lock_guard, unique_lock)以及更高级一点的condition variable。

0x01 Thread Group

Thread group其实和thread没有太大的区别,就是把线程放到一起使用简单的操作进行批量处理,根据http://www.boost.org/doc/libs/1_53_0/boost/thread/detail/thread_group.hpp,总共有以下几个操作,

  • thread* create_thread(F threadfunc); //创建新线程
  • void add_thread(thread* thrd); //添加线程
  • void remove_thread(thread* thrd); // 删除线程
  • void join_all(); // 等待所有线程结束
  • void interrupt_all(); // 中断所有线程
  • size_t size() const; // 返回线程数量

0x02 Mutex

多线程访问共享变量时,如果不对共享变量做一定的限制,由于线程的随机性,可能就会造成无法预知的结果,而这其中最简单也是目前最常用的方式就是互斥锁,也就是每次只允许一个线程访问,如果已经有一个线程在访问共享变量其他线程再访问时则会进入阻塞状态,从而保证程序的确定性与一致性,一个简单的例子如下,

#include "boost/thread.hpp"
#include <iostream>
using namespace std;

boost::mutex mutex;
int id = 0;

void work(){
    mutex.lock();
    id++;
    cout << << "id: " << id << endl;
    mutex.unlock();
}

int main(){
  boost::thread_group threads;
  for(int i=0;i<10;i++){
      threads.create_thread(&work);
  }
  threads.join_all();
  return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

0x03 lock_guard

lock_guard 相比于mutex 而言使用方法更为简单一点,

#include "boost/thread.hpp"
#include <iostream>
using namespace std;

boost::mutex mutex;
int id = 0;

void work(){
    { // 可以额外添加个大括号,来限制lock_guard的作用域
    boost::lock_guard<boost::mutex> lock(mutex);
    id++;
    cout << << "id: " << id << endl;
    }
}

int main(){
  boost::thread_group threads;
  for(int i=0;i<10;i++){
      threads.create_thread(&work);
  }
  threads.join_all();
  return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

lock_guard 能够在变量创建时自动加锁,在离开作用域(被析构)时自动解锁,所以使用更加方便,也不用担心忘记解锁。

0x03 unique lock

unique_lock 在用法上和lock_guard 类似,在一般的情况下使用lock_guard 就够了,但是unique_lock 比lock_guard 多了许多其他的特性,比如说在创建变量过一段时间后再进行锁定,也可以在析构函数执行之前就进行解锁,同时还可以配合condition_variable 在特定条件下进行解锁。

0x04 condition variable

代码转自: https://segmentfault.com/a/1190000006679917

#include <iostream>
#include <string>
#include <boost/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>

boost::mutex mtx;
boost::condition_variable cv;
std::string data;
bool ready = false;
bool processed = false;

void Worker() {
  boost::unique_lock<boost::mutex> lock(mtx);

  // 等待主线程发送数据。
  cv.wait(lock, [] { return ready; }); // 等价于 while(!ready){ cv.wait(lock); }

  // 等待后,继续拥有锁。
  std::cout << "工作线程正在处理数据..." << std::endl;
  // 睡眠一秒以模拟数据处理。
  boost::this_thread::sleep_for(boost::chrono::seconds(1));
  data += " 已处理";

  // 把数据发回主线程。
  processed = true;
  std::cout << "工作线程通知数据已经处理完毕。" << std::endl;

  // 通知前,手动解锁以防正在等待的线程被唤醒后又立即被阻塞。
  lock.unlock();
  cv.notify_one();
}

int main() {
  boost::thread worker(Worker);

  // 把数据发送给工作线程。
  {
    boost::lock_guard<boost::mutex> lock(mtx);
    std::cout << "主线程正在准备数据..." << std::endl;
    // 睡眠一秒以模拟数据准备。
    boost::this_thread::sleep_for(boost::chrono::seconds(1));
    data = "样本数据";
    ready = true;
    std::cout << "主线程通知数据已经准备完毕。" << std::endl;
  }
  cv.notify_one();

  // 等待工作线程处理数据。
  {
    boost::unique_lock<boost::mutex> lock(mtx);
    cv.wait(lock, [] { return processed; });
  }
  std::cout << "回到主线程,数据 = " << data << std::endl;

  worker.join();
  return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

这段程序很好的描述了condition_variable 的功能,使用这个功能主要有以下三个步骤:

  • 申明变量:一个boost::condition_variable cv 和一个boost::unique_lock<boost::mutex> lock(mtx); 类型,注意必须是unique_lock 类型,不能是其他的类型。
  • 阻塞当前线程: 有两种形式,一种是使用匿名函数 cv.wait(lock, []{return ready;}); 另一种是直接使用循环while(!ready){cv.wait(lock);}。
  • 修改变量并唤醒线程: ready = true; cv.notify_one(); 也可以同时唤醒多个线程cv.notify_all()。

    需要注意的是,在wait被唤醒之后进程依然拥有lock,只不过这时候就回归了lock_guard 功能,离开作用域后就自动解锁。

0x05 scoped lock

scoped_lock 就是typedef unique_lock<mutex> scoped_lock; 所以实际上和unique_lock 具有相同的功能

C++ Boost并发编程实战:从线程同步到高性能应用开发 并发编程是现代软件开发的核心技术之一,它通过多线程机制实现任务的逻辑同时执行,从而提升程序性能。其基本原理在于操作系统对线程的调度与管理,关键技术价值体现在充分利用多核CPU资源、优化I/O密集型任务响应时间。在C++生态中,Boost.Thread库作为C++11标准库的重要先驱,提供了跨平台的线程管理、互斥锁、条件变量等同步原语,是构建高性能网络服务器、数据处理引擎等复杂系统的基石。本文聚焦于Boost并发编程的实战应用,深入解析线程同步机制与性能优化策略,帮助开发者掌握构建健壮高效并发系统的关键技能。 阅读详情

相关推荐

C++并发库总结及boost.thread代码举例

在线程函数`threadFunction`中,我们先上锁`mtx`,然后对共享数据`sharedData`进行修改并打印出当前线程的ID和共享数据的值,最后休眠一段时间。在`main`函数中,我们创建了两个线程`t1`和`t2`,分别调用了线程函数`threadFunction`。2. std::mutex、std::lock_guard和std::unique_lock:C++11引入的标准库,提供了互斥量和锁的支持,用于保护共享资源的并发访问。

weixin_42009376的博客 320

C/C++基础,Boost创建线程、线程同步

C/C++基础,ROS中boost::bind的使用

qq_34761779的博客 2561

【BOOST C++ 线程】boost::thread库的基本使用方法总结

boost::thread的六种使用方法总结,本文初步介绍线程的函数、构造、执行的详细解释。

gongdiwudu的专栏 9458

C++ boost::thread_group 编程

多线程编程

那年聪聪 3031

使用boost::thread进行并发编程的测试程序

在这样的背景下,boost::thread作为一个开源的多线程库,提供了一种方便快捷的方式来实现跨平台的多线程编程。需要注意的是,由于boost::thread库是一个开源的多线程库,因此在使用之前,需要将其安装到我们的操作系统中。总之,通过本文所介绍的测试程序,我们可以看到boost::thread库提供了非常方便易用的接口,能够轻松地实现并发编程。为了演示boost::thread的使用方法,我们编写了一个简单的程序,其中包含两个子线程,它们分别打印出“Hello”和“World”两个字符串。

DevForge的博客 118

使用boost::thread的C++测试程序

使用boost::thread库可以方便地创建和管理线程,实现并发编程。你可以根据自己的需求定义线程函数,并使用boost::thread来创建和启动线程。同时,你还可以使用其他的boost线程库提供的功能,如线程同步、互斥锁等,来实现更复杂的并发算法和数据结构。以下是一个使用boost::thread库的测试程序,用于展示使用多线程进行并发编程的基本概念和用法。boost::thread是一个跨平台的C++线程库,提供了创建和管理线程的功能。这两个线程并发执行,可以看到它们的输出可能交错出现。

PixelProX的博客 85

C++ Boost Thread 编程总结

标准C++线程即将到来。CUJ预言它将衍生自Boost线程库,现在就由Bill带领我们探索一下Boost线程库。就在几年前,用多线程执行程序还是一件非比寻常的事。然而今天互联网应用服务程序普遍使用多线程来提高与多客户链接时的效率;为了达到最大的吞吐量,事务服务器在单独的线程上运行服务程序;GUI应用程序将那些费时,复杂的处理以线程的形式单独运行,以此来保证用户界面能够及时响应用户的操作。这样使用多线程的例子还有很多。但是C++标准并没有涉及到多线程,这让程序员们开始怀疑是否可能写出多线程的C++程序。

qq_40464599的博客 381

Boost Thread DLL在Windows环境下的应用与示例

在进行多线程编程时,线程的创建和管理是核心任务之一。Boost.Thread库提供了一套丰富的API来处理线程对象和线程管理。首先,Boost.Thread允许我们创建线程对象,这个对象包含了线程的运行状态、ID等信息,它是线程管理的基础。创建线程对象通常会用到类:// 线程将要执行的任务// 创建线程对象t执行task函数// 其他代码...t.join();// 等待线程t完成return 0;在上述示例中,

weixin_42452924的博客 995

【C++高性能并发编程终极指南】:掌握Boost.Asio与Boost.Thread核心技巧

掌握C++高性能并发编程核心方法,深入解析c++高性能并发库boost使用技巧。涵盖Boost.Asio异步IO与Boost.Thread多线程实战应用,提升系统性能与响应速度。适用于高并发网络服务与实时系统开发,值得收藏。

VarLens的博客 330

【OpenAirInterface知识-3】OAI端到端部署之5G基站部署

在上一篇文章中已经完成了5G核心网的部署,本篇文章将介绍OAI 5G基站的部署过程。

起名字难上难的博客 3421

CentOS Stream 9中安装MySQL的详细步骤

本文详细介绍了在CentOS Stream 9系统中如何进行MySQL的在线安装、离线安装以及忘记密码的恢复操作。通过阅读本文,您将能够了解并掌握在CentOS Stream 9上安装MySQL的步骤,以及在遇到忘记密码的情况下的解决方案。

小白典的博客 7258

boost::thread库 并发编程

所在文件和命名空间:#include <boost/thread.hpp> using namespace boost;1. 时间功能多线程编程经常要用到超时处理,需要表示时间的概念,thread库直接利用date_tiem库提供对时间的支持。this_thread::sleep(posix_time::seconds(2)); //当前线程睡眠两秒 //this_thread是thread的子命

yvhqbat的博客 3326

29、固态变压器拓扑、设计及其应用深度解析

本文深入解析了固态变压器(SST)的拓扑结构、设计方法及其在智能电网和能源互联网中的应用。重点探讨了机器学习在SST优化设计中的应用,包括中高频变压器设计、整体系统优化与建模研究。文章详细介绍了多端口SST的拓扑特点、功率传输机制及其作为能源路由器的关键作用,分析了不同端口数量下的控制复杂度与应用场景,并通过案例研究展示了四端口SST在分布式能源系统中的实际应用。最后,文章总结了多端口SST面临的技术挑战,并展望了未来在先进控制策略、集成化设计和标准化方面的发展方向。

study的专栏 3793

[Boost基础]并发编程——Thread多线程(一)

并发编程 并发编程:C++中没有语言级别的并发支持,因为在C++诞生很久以后线程等用于并发操作的概念才出现(POSIX线程标准制定与1955年)。但在现在随着拥有多CPU,多内核的计算机的大量出现,C++特别是C++标准没有定义并发操作的规范就显得有些过时了。并发编程是一个很广泛的话题,同时又是一门很复杂的技术。 Boost中有两个用于并发编程的组件。首先是thead库:它为C++增加了可移植

超越 6675

教师模型与学生模型:知识蒸馏的核心概念

知识蒸馏,教师模型,学生模型,模型压缩,迁移学习,深度学习 1. 背景介绍 深度学习模型在图像识别、自然语言处理等领域取得了显著的成就,但其巨大的模型规模和高昂的计算成本限制了其在资源有限的设备上的部署。知识蒸馏(Knowledge Distillation)作为一种模型压缩技术,旨

AI架构师小马 2772

QGis二次开发 —— 1、win10/win11搭建Vs2017-QGis3.40.12环境(附Vs2017环境效果,附全部问题解决方法)(附:Qt助手加入QGis接口说明文档)

QGis二次开发 —— 1、Windows10搭建Vs2017-QGis环境(附Vs2017环境效果)(附:Qt助手加入QGisA接口说明文档)

1362

[Boost基础]并发编程——Thread多线程(三)

线程组 thread库提供类thread_group用于管理一组线程,就像是一个线程池,它内部使用std::list来容纳创建的thread对象。成员函数有:and_thread(),remove_thread(),join_all(),interrupt_all() 条件变量 条件变量时thread库提供的另一种用于等待的同步机制,可以实现线程间的通信,它必须与互斥量配合使用,等待另一个线

超越 2104

43、FMCW雷达高度计仿真

本文介绍了FMCW雷达高度计的波形级建模与仿真过程,重点模拟了着陆和倾斜两种飞行场景以评估其性能。通过结合高程数据和飞行轨迹构建雷达场景,使用自定义信号处理器分析IQ样本并估计高度。结果表明,该高度计在多数情况下满足性能要求,但也存在误差较大的点,提出了地面检测算法优化的潜在方向。

neovim7hacker的博客 135

[Boost基础]并发编程——Thread多线程(二)

操作线程 thread类还提供了3个很有用的静态成员函数yield(),sleep(),hardware_concurrency() yield()函数指示当前线程放弃时间片,允许其他的线程运行;暂停当前正在执行的线程对象,并执行其他线程(注意:这里的其他包括当前线程) sleep()让线程睡眠等待一小段时间,注意它要求的参数是一个system_time UTC时间点而不是时间长度;使当前线

超越 2949

京东豆自动领取脚本配置教程

腾讯云/阿里云服务器(Docker环境):全自动跑脚本领京豆(无需本地代理,使用加速源)

AIOT魔法师 862

数据处理和分析之数据聚类:层次聚类(Hierarchical Clustering):单链接层次聚类方法

单链接层次聚类(Single-Linkage Hierarchical Clustering)是凝聚型层次聚类的一种,它基于数据点之间的最小距离来定义聚类间的相似性。在单链接层次聚类中,两个聚类之间的距离定义为这两个聚类中任意两个数据点之间的最短距离。这种聚类方法倾向于形成链状或线性的聚类,因为聚类的边界是由最远的数据点决定的,而不是聚类的平均或中心位置。单链接层次聚类通过计算簇间最近点的距离来决定簇的合并,这种方法简单直观,但可能导致簇的形状不规则,尤其是在数据点分布不均匀的情况下。

2401_87715305的博客 1443

Boost - 并行计算

本文介绍了并行计算的核心概念及其在Boost库中的实现方式。主要内容包括:1) 并行计算的基本思想及其复杂性,强调阿姆达尔定律的应用;2) Boost提供的多种并行工具库,如Thread、Asio、Compute等;3) 并行计算在科学计算、机器学习、游戏等领域的应用场景;4) 三个具体实现样例:多线程任务、线程池和消息队列的代码示例。文章指出并行计算虽然能提高性能,但需要谨慎处理并发问题,并选择合适的应用场景。

877

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C++的并发编程库有哪些?

【代码】C++的并发编程库有哪些?

kpvmjm9055q的博客 476

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

boost thread 判断是否正在运行_Java 并发编程实战:如何创建并运行java线程

在计算机世界中,并发是指一系列相互无关的任务在一台计算机上同时运行。对于有多个处理器或者多核处理器的计算机来说,这个同时性是真实发生的。然而,对于只有单核处理器的计算机来说,它仅仅是表面现象。所有现代操作系统均支持并发地执行任务。用户可以在听音乐或者浏览网页的同时阅读邮件。这种并发是进程级别的并发。在同一进程内,也可以有多种同时运行的子任务,我们将这些并发的子任务称为线程。与并发性有关的另一个概念...

weixin_42121086的博客 337

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

boost::thread的六种使用方法总结

近期在使用sqlite3作为缓存和文件数据库,用于存储micros的落盘数据和实时缓存。其中在作为落盘数据库的时候,为了增加插入效率,我们采用批量插入,但是批量数据来源不是直接来自实时缓存,我们设计了2级缓存RingBuffer,当Ringbuffer中的数据快满的时候,我们才批量写向文件数据库,为此需要开启一个线程监听RingBuffer,实现读写并行。 原来没有使用过boost的thread...

jinking01的专栏 1133

boost thread test example C++

Boost thread test example, built and tested on Ubuntu 64-bit Linux.   //build it: //g++ xxx.cpp -lboost_thread-mt #include #include #include #include using namespace std; void t

whq_1030的专栏 1088
上一篇: 区块链数据类型之大整数
下一篇: Java注解全面解析
TuxedoLinux
博客等级 码龄9年 268粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值