C++多线程-chap2多线程通信和同步9
这里,只是记录自己的学习笔记。
这里是重构了前面的一个工程。
xthread.h
1 #pragma once 2 #include <thread> 3 4 class XThread 5 { 6 public: 7 //启动线程 8 virtual void Start(); 9 10 //设置线程退出标志 并等待 11 virtual void Stop(); 12 13 //等待线程退出(阻塞) 14 virtual void Wait(); 15 16 //线程是否退出 17 bool is_exit(); 18 19 protected: 20 bool is_exit_ = false; 21 22 private: 23 //线程入口 24 virtual void Main() = 0; 25 26 std::thread th_; 27 };
xthread.cpp
1 #include "xthread.h" 2 3 using namespace std; 4 5 6 //启动线程 7 void XThread::Start() { 8 is_exit_ = false; 9 th_ = thread(&XThread::Main, this); 10 } 11 12 //设置线程退出标志 并等待 13 void XThread::Stop() { 14 is_exit_ = true; 15 Wait(); 16 } 17 18 //等待线程退出(阻塞) 19 void XThread::Wait() { 20 if (th_.joinable()) { 21 th_.join(); 22 } 23 } 24 25 //线程是否退出 26 bool XThread::is_exit() { 27 return is_exit_; 28 }
xmsg_server.h
1 #pragma once 2 #include "xthread.h" 3 #include <string> 4 #include <list> 5 #include <mutex> 6 class XMsgServer:public XThread 7 { 8 public: 9 //给当前线程发消息 10 void SendMsg(std::string msg); 11 void Stop() override; 12 private: 13 //处理消息的线程入口函数 14 void Main() override; 15 16 //可以考虑给消息队列设置一个最大值,超过最大值就阻塞,或者发送失败等等 17 //消息队列缓冲 18 std::list<std::string> msgs_; 19 20 //互斥访问消息队列 21 std::mutex mux_; 22 23 std::condition_variable cv_; 24 }; 25 26 //使用互斥锁 + list 模拟 线程通信 27 //1.封装线程基类 XThread 控制线程启动和停止 28 //2.模拟消息服务器线程,接收字符串消息,并模拟处理 29 //3.通过 unique_lock 和 mutex 互斥访问 list<string> 消息队列 30 //4.主线程定时发送消息给子线程 31 //
xmsg_server.cpp
重写了Stop函数
#include "xmsg_server.h" #include <iostream> using namespace std; using namespace this_thread; void XMsgServer::Stop() { is_exit_ = true; cv_.notify_all(); Wait(); } //给当前线程发消息 void XMsgServer::SendMsg(std::string msg) { unique_lock<mutex> lock(mux_); msgs_.push_back(msg); lock.unlock(); cv_.notify_one(); } //处理消息的线程入口函数 void XMsgServer::Main() { while(!is_exit()) { unique_lock<mutex> lock(mux_); cv_.wait(lock, [this] { cout << "wait cv" << endl; if (is_exit()) return true; //处理退出逻辑 return !msgs_.empty(); }); while (!msgs_.empty()) { //消息处理业务逻辑 cout << "recv : " << msgs_.front() << endl; msgs_.pop_front(); } } }
hello.cpp
1 #include <iostream> 2 #include <string> 3 #include <mutex> 4 #include <thread> 5 #include "xmsg_server.h" 6 #include <sstream> 7 using namespace std; 8 9 int main() 10 { 11 XMsgServer server; 12 server.Start(); 13 for (int i = 0; i < 10; i++) { 14 stringstream ss; 15 ss << " msg : " << i + 1; 16 server.SendMsg(ss.str()); 17 this_thread::sleep_for(500ms); 18 } 19 20 server.Stop(); 21 cout << "Server stoped!" << endl; 22 return 0; 23 }