1. 程式人生 > 其它 >C++多執行緒-chap2多執行緒通訊和同步9

C++多執行緒-chap2多執行緒通訊和同步9

這裡,只是記錄自己的學習筆記。

順便和大家分享多執行緒的基礎知識。然後從入門到實戰。有程式碼。

知識點來源:

https://edu.51cto.com/course/26869.html


條件變數應用執行緒通訊解決執行緒退出時的阻塞問題

這裡是重構了前面的一個工程。

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 }

 

 

作者:小烏龜 出處:http://www.cnblogs.com/music-liang/ 【轉載請註明出處,歡迎轉載】 希望這篇文章能幫到你