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

运行结果:

相关推荐
倒头就睡的小比特5 天前
算法竞赛C++常用的STL
c++·算法
weilx12345 天前
C++笔记-文件IO-<fcntl.h>
c++
小羊没烦恼!5 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
伞伞悦读5 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
Smileyqp沛沛5 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车5 天前
C/C++ 为什么需要编译器?
开发语言·c++
旖旎夜光5 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
吞下星星的少年·-·5 天前
C++ 萌新语法入门篇
c++·算法比赛
霍霍的袁5 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
another heaven5 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法