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;
}

运行结果:

相关推荐
毕设源码-郭学长1 分钟前
【开题答辩全过程】以 基于python的二手房数据分析与可视化为例,包含答辩的问题和答案
开发语言·python·数据分析
无小道24 分钟前
Qt——常用控件
开发语言·qt
aini_lovee41 分钟前
MATLAB基于小波技术的图像融合实现
开发语言·人工智能·matlab
R1nG8631 小时前
多线程安全设计 CANN Runtime关键数据结构的锁优化
开发语言·cann
初次见面我叫泰隆1 小时前
Qt——5、Qt系统相关
开发语言·qt·客户端开发
亓才孓1 小时前
[Class的应用]获取类的信息
java·开发语言
初願致夕霞1 小时前
Linux_进程
linux·c++
开开心心就好1 小时前
AI人声伴奏分离工具,离线提取伴奏K歌用
java·linux·开发语言·网络·人工智能·电脑·blender
Never_Satisfied1 小时前
在JavaScript / HTML中,关于querySelectorAll方法
开发语言·javascript·html
Thera7772 小时前
【Linux C++】彻底解决僵尸进程:waitpid(WNOHANG) 与 SA_NOCLDWAIT
linux·服务器·c++