参考引用

1. 利用特性自动释放锁 RAII

1.1 什么是 RAII

1.2 手动实现 RAII 管理 mutex 资源

2. lock_guard:C++11 支持的 RAII 管理互斥资源

3. unique_lock:C++11 实现移动互斥所有权包装

4. shared_lock C++14 实现移动共享互斥体所有权封装

int main(int argc, char* argv[]) {
    {
        // 共享
        static shared_timed_mutex tmux;
    
        // 读取锁--共享锁
        {
            // 调用共享锁 
            shared_lock<shared_timed_mutex> lock(tmux);
            cout << "read data" << endl;
            // 退出栈区 释放共享锁
        }
    
        // 写入锁--互斥锁
        {
            unique_lock<shared_timed_mutex> lock(tmux);
            cout << "write data" << endl;
        }
    }
}

5. 案例:使用互斥锁和 List 实现多线程通信

5.1 xthread.h

#pragma once
#include <thread>

class XThread {
public:
    // 启动线程
    virtual void Start();

    // 设置线程退出标志 并等待
    virtual void Stop();

    // 等待线程退出(阻塞
    virtual void Wait();

    // 线程是否退出
    bool is_exit();

private:
    // 线程入口
    virtual void Main() = 0;
    bool is_exit_ = false;
    std::thread th_;
};

5.2 xthread.cpp

#include "xthread.h"

using namespace std;

// 启动线程
void XThread::Start() {
    is_exit_ = false;
    th_ = thread(&amp;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_;
}

5.3 xmsg_server.h

#pragma once
#include "xthread.h"
#include <string>
#include <list>
#include <mutex>

class XMsgServer : public XThread {
public:
    // 给当前线程发消息
    void SendMsg(std::string msg);

private:
    // 处理消息的线程入口函数
    void Main() override;

    // 消息队列缓冲
    std::list<std::string> msgs_;

    // 互斥访问消息队列
    std::mutex mux_;
};

5.4 xmsg_server.cpp

#include "xmsg_server.h"
#include <iostream>

using namespace std;
using namespace this_thread;

// 处理消息的线程入口函数
void XMsgServer::Main() {
    while (!is_exit()) {
        sleep_for(10ms);
        unique_lock<mutex> lock(mux_);
        if (msgs_.empty())
            continue;
        while (!msgs_.empty()) {
            // 消息处理业务逻辑
            cout << "recv : " << msgs_.front() << endl;
            msgs_.pop_front();
        }

    }
}

// 给当前线程发消息
void XMsgServer::SendMsg(std::string msg) {
    unique_lock<mutex> lock(mux_);
    msgs_.push_back(msg);
}

5.5 thread_msg_server

#include "xmsg_server.h"
#include <sstream>

using namespace std;

int main(int argc, char* argv[]) {
    XMsgServer server;
    server.Start();
    for (int i = 0; i < 10; i++) {
        stringstream ss;
        ss << " msg : " << i + 1;
        server.SendMsg(ss.str());
        this_thread::sleep_for(500ms);
    }
    server.Stop();

    return 0;
}

6. 条件变量应用场景_生产者消费者信号处理步骤

6.1 改变共享变量的线程步骤

6.2 等待信号读取共享变量的线程步骤

7. condition_variable 读写线程同步

#include <thread>
#include <iostream>
#include <mutex>
#include <list>
#include <string>
#include <sstream>

using namespace std;

list<string> msgs_;
mutex mux;
condition_variable cv;

void ThreadWrite() {
    for (int i = 0;;i++) {
        stringstream ss;
        ss << "Write msg " << i;
        unique_lock<mutex> lock(mux);
        msgs_.push_back(ss.str());
        lock.unlock();
        cv.notify_one();  // 发送信号
        //cv.notify_all();
        this_thread::sleep_for(3s);
    }
}
void ThreadRead(int i) {
    for (;;) {
        cout << "read msg" << endl;
        unique_lock<mutex> lock(mux);
        //cv.wait(lock);  // 解锁、阻塞等待信号
        cv.wait(lock, [i] 
            {
                cout << i << " wait" << endl;
                return !msgs_.empty(); 
            });
        // 获取信号后锁定
        while (!msgs_.empty()) {
            cout << i << " read " << msgs_.front() << endl;
            msgs_.pop_front();
        }

    }
}
int main(int argc, char* argv[]) {
    thread th(ThreadWrite);
    th.detach();
    for (int i = 0; i < 3; i++)  {
        thread th(ThreadRead, i + 1);
        th.detach();
    }
    getchar();

    return 0;
}

原文地址:https://blog.csdn.net/qq_42994487/article/details/134634570

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_22730.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注