Boost多线程编程

目录

thread

[thread 类总览](#thread 类总览)

构造函数

[= join joinable](#= join joinable)

[detach swap](#detach swap)

成员函数的调用

namespace::this_thread​编辑​编辑

互斥量Mutex

互斥锁mutex

递归锁recursive_mutex

定时锁

Lock

lock_guard

unique_lock

[std::lock 解决死锁问题](#std::lock 解决死锁问题)

消息队列

condition_variable

condition_variable

生产者消费者模型

atomic

atmoic

atomic_flag

[chrono 时间库](#chrono 时间库)


thread

thread 类总览

构造函数

= join joinable

C++ std::thread join()的理解 - 代萌 - 博客园

  • **谁调用了这个函数?**调用了这个函数的线程对象,一定要等这个线程对象的方法(在构造时传入的方法)执行完毕后(或者理解为这个线程的活干完了!),这个join()函数才能得到返回。

  • 在什么线程环境下调用了这个函数? 上面说了必须要等线程方法执行完毕后才能返回,那必然是阻塞调用线程的,也就是说如果一个线程对象在一个线程环境调用了这个函数,那么这个线程环境就会被阻塞,直到这个线程对象在构造时传入的方法执行完毕后,才能继续往下走,另外如果线程对象在调用join()函数之前,就已经做完了自己的事情(在构造时传入的方法执行完毕),那么这个函数不会阻塞线程环境,线程环境正常执行。


detach swap

成员函数的调用

必须传入成员函数地址和调用的对象

namespace::this_thread

互斥量Mutex

互斥锁mutex


递归锁recursive_mutex

递归锁出现的意义:假设存在这样一个场景,一个函数使用mutex 同时调用另外的一个函数里面有用到同一个mutex,则此时同一个互斥量被上了两次锁,导致死锁;而递归锁可以对互斥量拥有多层所有权,可以避免死锁;

同一个线程多次占用(递归占用次数有限,不能太多),可配合lock_guard使用,不通线程和互斥锁一致。

定时锁

Lock

lock_guard


unique_lock


std::lock 解决死锁问题

多线程共享数据的保护+互斥量概念、用法、死锁演示及解决详解(std::lock()、std::adopt_lock)_c# 两个线程共享数组保护-CSDN博客

消息队列

cpp 复制代码
#include <list>
#include <thread>
#include <mutex>
#include<iostream>

class A
{
public:
    //把收到的消息(玩家命令)入到一个队列的线程
    void inMsgRecvQueue()
    {
        for (int i = 0;i < 100;++i)
        {
            cout << "inMsgRecvQueue()执行,插入一个元素" << i << endl;
            my_mutex.lock();
            msgRecvQueue.push_back(i);
            my_mutex.unlock();
        }
    }

    bool outMsgLULProc(int& command)
    {
        // my_mutex.lock();
        std::lock_guard<std::mutex> sguard(my_mutex);
        if (!msgRecvQueue.empty())
        {
            command = msgRecvQueue.front();
            msgRecvQueue.pop_front();
            // my_mutex.unlock();
            return true;
        }
        // my_mutex.unlock();
        return false; 
    }

    //把数据从消息队列中取出的线程
    void outMsgRecvQueue()
    {
        int command = 0;
        for (int i = 0;i < 100;i++)
        {
            bool result = outMsgLULProc(command);
            if (result == true)
            {
                cout << "outMsgRecvQueue()执行,取出一个元素" << command << endl;
                //可以考虑对命令(数据)进行处理
            }
            else
            {
                cout << "outMsgRecvQueue()执行,但是目前消息队列中为空" << i << endl;
            }
        }
        cout << "end" << endl;
    }

private:
    std::list<int> msgRecvQueue;    //容器,专门用于代表玩家发送过来的命令
    std::mutex my_mutex; //创建一个互斥量 
};

int main()
{
    A myobja;
    std::thread myOutnMsgObj(&A::outMsgRecvQueue,&myobja);
    std::thread myInMsgObj(&A::inMsgRecvQueue,&myobja);
    myInMsgObj.join();
    myOutnMsgObj.join();
    return 0;
}

condition_variable


condition_variable

生产者消费者模型

cpp 复制代码
condition_variable.h头文件
    
#include <mutex>
#include <thread>
#include <chrono>
#include <deque>
#include <condition_variable>

namespace TestConditional_variable
{
	extern std::mutex g_cvMutex;
	extern std::condition_variable g_cv;
	extern std::deque<int>g_data_deque;
	extern const int MAX_NUM;
	extern int g_next_index;

	const int PRODUCER_THREAD_NUM = 3;
	const int CONSUMER_THREAD_NUM = 3;

	void producer_thread(int thread_id);
	void consumer_thread(int thread_id);

}
cpp 复制代码
condition_variable.cpp头文件
    
#include"Condition_variable.h"
#include<iostream>
namespace TestConditional_variable {

	 std::mutex g_cvMutex;
	 std::condition_variable g_cv;
	 std::deque<int>g_data_deque;
	 const int MAX_NUM = 30;

	 int g_next_index = 0;
	
	void producer_thread(int thread_id)
	{
		for (int i = 0; i < 4;i++)
		{
			std::this_thread::sleep_for(std::chrono::milliseconds(500));
			std::unique_lock<std::mutex>lk(g_cvMutex);
			g_cv.wait(lk, [](){return g_data_deque.size() <= MAX_NUM; });
            //wait的第二个参数为可执行的OBJ 反复执行直到返回true
			g_next_index++;
			g_data_deque.push_back(g_next_index);
			std::cout << "producer_thread" << thread_id << " producer data" << g_next_index;
			std::cout << " queue size:" << g_data_deque.size() << std::endl;
			g_cv.notify_all();
		}
	}

	void consumer_thread(int thread_id)
	{
		for (int i = 0; i < 4; i++)
		{
			std::this_thread::sleep_for(std::chrono::milliseconds(500));
			std::unique_lock<std::mutex>lk(g_cvMutex);
			g_cv.wait(lk, [](){return !g_data_deque.empty(); });
			g_next_index++;
			int data = g_data_deque.front();
			g_data_deque.pop_front();
			std::cout << "consumer_thread" << thread_id << " consumer data" << g_next_index;
			std::cout << " queue size:" << g_data_deque.size() << std::endl;
			g_cv.notify_all();
		}
	}

}
cpp 复制代码
#include"Condition_variable.h"
#include<iostream>

int main(int argc, char *argv[])
{
	std::thread arrProducerThread[TestConditional_variable::PRODUCER_THREAD_NUM];
	std::thread arrConsumerThread[TestConditional_variable::CONSUMER_THREAD_NUM];

	for (int i = 0; i < TestConditional_variable::PRODUCER_THREAD_NUM; i++)
	{
		arrProducerThread[i] = std::thread(TestConditional_variable::producer_thread, i);
	}
	for (int i = 0; i < TestConditional_variable::CONSUMER_THREAD_NUM; i++)
	{
		arrConsumerThread[i] = std::thread(TestConditional_variable::consumer_thread, i);
	}
	for (int i = 0; i < TestConditional_variable::PRODUCER_THREAD_NUM; i++)
	{
		arrProducerThread[i].join();
	}
	for (int i = 0; i < TestConditional_variable::CONSUMER_THREAD_NUM; i++)
	{
		arrConsumerThread[i].join();
	}
	return 0;
}

atomic

复制代码
#include<atomic>
class atomic
class atomic_flag

atmoic

atomic_flag

chrono 时间库

相关推荐
free-elcmacom1 分钟前
C++学习<1>程序分区
开发语言·c++
醉颜凉8 分钟前
Java 必看:如何彻底避免 HashMap 多线程死循环问题?
java·开发语言
默 语9 分钟前
Java新手入门:从零开始安装JDK并配置环境变量
java·开发语言·python·mysql·group by·1024程序员节·数据去重
Brilliantwxx35 分钟前
【STM32】 I2C_EEPROM_test 工程(实战篇)
开发语言·stm32·单片机·嵌入式硬件·ecmascript
清水白石00840 分钟前
Python 异步编程深度解析:Cancellation 到底是异常还是控制信号?从 asyncio 取消机制到企业级事务设计最佳实践
开发语言·python
kolyle1 小时前
万级 QPS 下的 Token 分发系统架构:从 0 到 1 跑通 AI 时代的“水电煤“
开发语言·人工智能·系统架构·token·qps·极智词元·大模型私有化部署
caoerzhong1 小时前
JeeWMS 开源仓库管理系统 GPL-3.0 合规指南:Java WMS 二次开发前必须弄清的授权边界
java·开发语言·开源·vue
Patrick在香港1 小时前
Python 审计香港开放数据目录:两个端点差 10 倍,只有 9.3% 的资源标了「最后修改时间」
开发语言·数据库·python·数据分析·api·数据治理·开放数据
Sylvia33.1 小时前
火星数据体育API|一站式接入足球篮球电竞等18+项目实时数据
java·开发语言·python·websocket·游戏
Data_Journal2 小时前
使用 AutoScraper 进行网页抓取:分步教程
大数据·开发语言·数据库·python·scrapy