主线程和子线程进行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;
}
运行结果: