首页 > 编程语言 >BOOST c++库学习 之 boost.thread入门实战指南 使用boost.thread库以及读写锁mutex的测试例程

BOOST c++库学习 之 boost.thread入门实战指南 使用boost.thread库以及读写锁mutex的测试例程

时间:2024-08-12 16:27:38浏览次数:9  
标签:thread 例程 data 线程 lock shared boost

Boost.Thread 库简介

1. 概述

Boost.Thread库是Boost库中专门用于处理多线程编程的模块。它提供了一组跨平台的线程管理和同步工具,帮助开发者在C++中更轻松地编写多线程程序。Boost.Thread的设计目标是使多线程编程更加简单、可靠,同时保持高效和可移植性。

2. Boost.Thread库主要提供以下功能:

2.1. 线程管理相关

  • boost::thread

    • boost::thread: 创建和管理线程的类。可以通过传递一个可调用对象(如函数指针、函数对象或lambda表达式)来创建一个线程。
      • 构造函数:boost::thread(boost::function<void()> f)
      • join(): 等待线程完成。
      • detach(): 分离线程,使其在后台运行。
  • boost::this_thread::get_id

    • 获取当前线程的ID。
  • boost::this_thread::sleep_for

    • 使当前线程休眠指定的时间段。
  • boost::this_thread::yield

    • 让出当前线程的执行权。

2.2. 互斥量相关

  • boost::mutex

    • 简单的互斥锁,用于保护共享数据的访问。
  • boost::recursive_mutex

    • 支持递归锁定的互斥量,允许同一线程多次加锁。
  • boost::shared_mutex

    • 读写锁,允许多个线程同时读取数据,但写操作是独占的。

2.3. 条件变量相关

  • boost::condition_variable

    • 条件变量,用于线程间的等待和通知机制。
  • boost::condition_variable_any

    • boost::condition_variable类似,但适用于任何锁类型。
  • wait()

    • 阻塞当前线程,直到收到通知。
      • 例:cond_var.wait(lock, predicate);
  • notify_one()

    • 通知一个等待的线程继续执行。
  • notify_all()

    • 通知所有等待的线程继续执行。

2.4. 锁管理相关

  • boost::unique_lock

    • 管理独占锁,通常用于与boost::mutex配合使用。
  • boost::shared_lock

    • 管理共享锁,通常用于与boost::shared_mutex配合使用。
  • boost::lock_guard

    • RAII风格的锁管理器,自动管理锁的获取和释放。
  • boost::try_lock

    • 尝试获取多个锁,如果无法获取所有锁,则释放已经获取的锁。

2.5. 其他

  • boost::thread_group

    • 管理一组线程的类,允许同时创建和管理多个线程。
  • boost::call_once

    • 保证某个函数或初始化操作只被调用一次。

这些是Boost.Thread库中最常用的一些类和函数。通过这些工具,开发者可以在C++中实现复杂的多线程程序,确保线程间的数据安全性和同步。

3. 应用场景

Boost.Thread库广泛应用于需要并发处理的C++项目中,例如:

  • 服务器开发: 在网络服务器中处理多个客户端请求。
  • 并行计算: 在科学计算中利用多核CPU进行并行计算。
  • 实时系统: 在嵌入式或实时系统中管理并发任务。

boost.thread库以及读写锁、互斥锁的测试例程、操作步骤

以下是一个使用Boost.Thread库的测试实例程序,它结合了读写锁、条件变量和锁管理机制。为了对比,还提供了一个没有使用这些同步机制的例子。

1. 使用同步机制的测试实例程序

#include <iostream>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>

// 全局数据和同步机制
int shared_data = 0;
boost::mutex mtx; // 互斥量
boost::shared_mutex rw_mtx; // 读写锁
boost::condition_variable_any cond_var; // 条件变量

// 写线程函数 - 使用互斥量和条件变量
void writer(int id) {
    boost::this_thread::sleep_for(boost::chrono::milliseconds(100 * id));

    // 使用unique_lock管理互斥量
    boost::unique_lock<boost::mutex> lock(mtx);

    shared_data += id;
    std::cout << "Writer " << id << " updated shared_data to " << shared_data << std::endl;

    // 通知等待条件变量的读者线程
    cond_var.notify_all();
}

// 读线程函数 - 使用读写锁和条件变量
void reader(int id) {
    boost::this_thread::sleep_for(boost::chrono::milliseconds(100 * id));

    // 等待条件变量
    {
        boost::unique_lock<boost::mutex> lock(mtx);
        cond_var.wait(lock, []{ return shared_data > 0; });
    }

    // 使用shared_lock管理读写锁(读锁)
    boost::shared_lock<boost::shared_mutex> read_lock(rw_mtx);
    std::cout << "Reader " << id << " reads shared_data: " << shared_data << std::endl;
}

int main() {
    boost::thread_group writers, readers;

    // 启动写线程
    for (int i = 1; i <= 3; ++i) {
        writers.create_thread(boost::bind(&writer, i));
    }

    // 启动读线程
    for (int i = 1; i <= 5; ++i) {
        readers.create_thread(boost::bind(&reader, i));
    }

    // 等待所有线程完成
    writers.join_all();
    readers.join_all();

    return 0;
}

2. 没有同步机制的对照例子

下面的代码示例没有使用任何同步机制,这样可以看到多线程程序在没有保护共享数据时可能产生的问题。

#include <iostream>
#include <boost/thread.hpp>
#include <boost/chrono.hpp>

// 全局数据
int shared_data = 0;

// 写线程函数 - 无同步机制
void writer(int id) {
    boost::this_thread::sleep_for(boost::chrono::milliseconds(100 * id));

    shared_data += id;
    std::cout << "Writer " << id << " updated shared_data to " << shared_data << std::endl;
}

// 读线程函数 - 无同步机制
void reader(int id) {
    boost::this_thread::sleep_for(boost::chrono::milliseconds(100 * id));

    std::cout << "Reader " << id << " reads shared_data: " << shared_data << std::endl;
}

int main() {
    boost::thread_group writers, readers;

    // 启动写线程
    for (int i = 1; i <= 3; ++i) {
        writers.create_thread(boost::bind(&writer, i));
    }

    // 启动读线程
    for (int i = 1; i <= 5; ++i) {
        readers.create_thread(boost::bind(&reader, i));
    }

    // 等待所有线程完成
    writers.join_all();
    readers.join_all();

    return 0;
}

3. 调试过程

3.1 启动使用同步机制的程序

编译并运行使用同步机制的程序,确保所有读写操作都按照预期执行,并且共享数据的一致性得到保护。

g++ -o boost_thread_sync boost_thread_sync.cpp -lboost_thread -lboost_system -pthread
./boost_thread_sync

3.2 启动没有同步机制的程序

编译并运行没有使用同步机制的程序,观察输出是否混乱或者数据不一致。

g++ -o boost_thread_no_sync boost_thread_no_sync.cpp -lboost_thread -lboost_system -pthread
./boost_thread_no_sync

4. 输出结果

4.1 使用同步机制的程序输出

Writer 1 updated shared_data to 1
Reader 1 reads shared_data: 1
Writer 2 updated shared_data to 3
Reader 2 reads shared_data: 3
Writer 3 updated shared_data to 6
Reader 3 reads shared_data: 6
Reader 4 reads shared_data: 6
Reader 5 reads shared_data: 6

4.2 没有使用同步机制的程序输出

Writer 1 updated shared_data to 1
Writer 2 updated shared_data to 3
Reader 1 reads shared_data: 3
Writer 3 updated shared_data to 6
Reader 2 reads shared_data: 6
Reader 3 reads shared_data: 6
Reader 4 reads shared_data: 3
Reader 5 reads shared_data: 6

5. 输出结果分析

  1. 使用同步机制的程序:共享数据在多个线程间保持了一致性,所有线程按照预期顺序读取和更新数据。

  2. 没有使用同步机制的程序:由于没有保护共享数据,多个线程同时读取或写入数据可能导致不一致的结果(如某些读线程读取到旧的或中间态的数据)。

6. 总结

通过对比这两个程序,展示了在多线程编程中使用同步机制(如读写锁和条件变量)的重要性。没有这些机制,多线程环境下的数据竞争会导致程序行为不可预测,而使用这些机制可以确保线程安全性和数据一致性。

标签:thread,例程,data,线程,lock,shared,boost
From: https://blog.csdn.net/weixin_44251074/article/details/141134156

相关文章

  • LeetCode 1834. Single-Threaded CPU
    原题链接在这里:https://leetcode.com/problems/single-threaded-cpu/description/题目:Youaregiven n​​​​​​taskslabeledfrom 0 to n-1 representedbya2Dintegerarray tasks,where tasks[i]=[enqueueTimei,processingTimei] meansthatthe i​​......
  • Python和多线程(multi-threading)
    在Python中,实现并行处理的方法有几种,但由于Python的全局解释器锁(GIL,GlobalInterpreterLock)的存在,传统意义上的多线程(使用threading模块)并不总能有效利用多核CPU来实现真正的并行计算。GIL确保任何时候只有一个线程在执行Python字节码。不过,仍然有几种方法可以绕过这个限制,......
  • 基于模糊pid的两路交错boost变换器Simulink仿真及代码自动生成(上)电路仿真部分
    后半部分已更新基于模糊pid的两路交错boost变换器Simulink仿真及代码自动生成(下)F280025实物测试部分简介:设计两路交错BOOST变换电路,搭建Simulink仿真模型,并设计控制算法(常规PID与模糊控制PID)。基于德州仪器TMS320F280025单片机使用MatlabCodeGenerationTools进行编程与实物测......
  • 基于模糊pid的两路交错boost变换器Simulink仿真及代码自动生成(下)F280025实物测试部分
    简介:设计两路交错BOOST变换电路,搭建Simulink仿真模型,并设计控制算法(常规PID与模糊控制PID)。基于德州仪器TMS320F280025单片机使用MatlabCodeGenerationTools进行编程与实物测试。电气系统建模与实践课程设计福州大学自动化系黄宸贞2024/3/28指导教师:蔡逢煌陈丹软件环境......
  • 基于LSTM-Adaboost的电力负荷预测(Matlab代码实现)
    ......
  • 佰泰盛世—HT5169内置BOOST升压的11WI2S输入D类音频功放
    1特性电源供电• 升压输入VBAT:2.5V-5.5V;• 升压输出PVDD可调,最高7.5V• DVDD/AVDD:3.3V音频性能•9.0W(VBAT=3.7V,PVDD=7.5V,RL=3Ω,THD+N=10%)•11.0W(VBAT=3.7V,PVDD=7.5V,RL=2Ω,THD+N=10%•5.5W(VBAT=3.7V,PVDD=6.5V,RL=4Ω,THD+N=10%)灵......
  • [Java并发]ThreadLocal补充
    ThreadLocal缺点及解决方案每个Thread上都有一个threadLocals属性,它是一个ThreadLocalMap,里面存放着一个Entry数组,key是ThreadLocal类型的弱引用,value是对用的值。所有的操作都是基于这个ThreadLocalMap操作的。但是它有一个局限性,就是不能在父子线程之间传递。即在子线程中无......
  • ThreadLocal
    为什么多线程需要加锁1.ThreadLocal的介绍从Java官方文档中的描述:ThreadLocal类用来提供线程内部的局部变量。这种变量子在多线程环境下访问(通过get和set方法)时能保证各个线程的变量相对独立于其他线程内的变量,ThreadLocal实例通常来说都是privatestatic类型的,用于关联......
  • Thread、ThreadPool、Task之间的联系
    1、ThreadPool线程池一个应用程序最多只能有一个线程池。线程池是一种多线程处理形式,通过QueueUserWorkItem()将任务添加到队列中,然后创建线程(后台线程,又称工作者线程)自动启动这些任务来处理。其中,最小线程数即核心线程数(corePoolSize)是线程池中长期保持的线程数,即使它们处于闲置......
  • 【Python机器学习】利用AdaBoost元算法提高分类性能——基于单层决策树构建弱分类器
    单层决策树(也称决策树桩)是一种简单的决策树。它基于单个特征来做决策,由于这棵树只有一次分裂过程,因此它实际上就是一个树桩。在构造AdaBoost代码时,首先通过一个简单数据集来确保在算法上一切就绪:fromnumpyimport*defloadSimpData():datMat=matrix([[1.0,2.1],......