C++多线程编程(第三章 案例1,使用互斥锁+ list模拟线程通信)

主线程和子线程进行list通信,要用到互斥锁,避免同时操作

1、封装线程基类XThread控制线程启动和停止;

2、模拟消息服务器线程,接收字符串消息,并模拟处理;

3、通过Unique_lock和mutex互斥方位list 消息队列

4、主线程定时发送消息给子线程;

代码包含了XThread类(基类)、XMsgSever类(消息)、测试主程序

cpp 复制代码
//XThread.h 类(基类)
#pragma once
#include <thread>

//基类
class XThread
{
public:
	virtual void Start();//启动线程
	virtual void Stop();//设置线程退出标志,并等待
	virtual void Wait();//等待
	virtual bool is_exit();//线程是否退出

private:
	virtual void Main() = 0;//线程入口,纯虚函数,子函数必须单独实现
	bool is_exit_ = false;
	std::thread th_;

};
cpp 复制代码
//XThread.cpp 类(基类)
#include "XThread.h"

using namespace std;//在CPP中引用using namespace
void XThread::Start()//启动线程
{
	is_exit_ = false;//不要退出
	th_ = thread(&XThread::Main,this);

}
void XThread::Stop()//设置线程退出标志,并等待
{
	is_exit_ = true;
	Wait();

}
void XThread::Wait()//等待
{
	if (th_.joinable())
	{
		th_.join();
	}

}
bool XThread::is_exit()//线程是否退出
{
	return is_exit_;
}
cpp 复制代码
//XMsgSever.h 类
#pragma once
#include "XThread.h"
#include <list>
#include <mutex>
class XMsgSever:public XThread
{
public:
	//给当前线程发消息
	void SendMsg(std::string msg);



private:
	void Main()override;//重写main,override检查名字是否写错

	
	std::list<std::string> msgs_;//消息队列缓冲

	std::mutex mux_;//互斥访问消息队列
};
cpp 复制代码
//XMsgSever.cpp 类
#include "XMsgSever.h"
#include <iostream>

using namespace std;


void XMsgSever::SendMsg(std::string msg)
{//消息生产者
	unique_lock<mutex> lock(mux_);//为了保证list的线程安全,加锁
	msgs_.push_back(msg);
}

void XMsgSever::Main()
{//消息消费者
	while (!is_exit())
	{
		this_thread::sleep_for(10ms);
		unique_lock<mutex> lock(mux_);
		if (msgs_.empty())
		{//如果没有消息,则continue
			continue;
		}
		while (!msgs_.empty())
		{//消息处理业务逻辑
			cout << "recv: " << msgs_.front().c_str() << endl;
			msgs_.pop_front();
		}

	}

}
cpp 复制代码
//测试主程序
/*

1、封装线程基类XThread控制线程启动和停止;
2、模拟消息服务器线程,接收字符串消息,并模拟处理;
3、通过Unique_lock和mutex互斥方位list<string> 消息队列
4、主线程定时发送消息给子线程;

*/

#include "XMsgSever.h"
#include <sstream>
using namespace std;

int main()
{
	XMsgSever server;
	server.Start();//启动子线程,调了Main入口,进入死循环消费信息了
	for (int i = 0; i < 10; i++)
	{
		stringstream ss;
		ss << "msg: " << i + 1;
		server.SendMsg(ss.str());
		this_thread::sleep_for(500ms);
	}
	server.Stop();
	printf("All done!\n");

	return 0;
}

运行结果:

相关推荐
山登绝顶我为峰 3(^v^)331 分钟前
如何录制带备注的演示文稿(LaTex Beamer + Pympress)
c++·线性代数·算法·计算机·密码学·音视频·latex
Python×CATIA工业智造3 小时前
Frida RPC高级应用:动态模拟执行Android so文件实战指南
开发语言·python·pycharm
十五年专注C++开发3 小时前
CMake基础:条件判断详解
c++·跨平台·cmake·自动化编译
我叫小白菜4 小时前
【Java_EE】单例模式、阻塞队列、线程池、定时器
java·开发语言
狐凄4 小时前
Python实例题:基于 Python 的简单聊天机器人
开发语言·python
weixin_446122465 小时前
JAVA内存区域划分
java·开发语言·redis
悦悦子a啊5 小时前
Python之--基本知识
开发语言·前端·python
QuantumStack6 小时前
【C++ 真题】P1104 生日
开发语言·c++·算法
天若有情6736 小时前
01_软件卓越之道:功能性与需求满足
c++·软件工程·软件
whoarethenext6 小时前
使用 C++/OpenCV 和 MFCC 构建双重认证智能门禁系统
开发语言·c++·opencv·mfcc