C++中的锁

常用的互斥锁: std::mutex​​(互斥对象),std::shared_mutex​​(读写互斥对象)

三个用于代替互斥对象的成员: 管理互斥对象的锁(都是构造加锁,析构解锁):std::lock_guard​ 用于管理 std::mutex​,std::unique_lock​ 与 std::shared_lock​ 管理 std::shared_mutex​。

读锁 ​shared_lock​ 与写锁 ​unique_lock​​: 读共享, 写独占. (c++17才提供支持)

lockguard 粒度大, 故可用 unique_lock 替代 lockguard, 精细控制何处 unlock 锁, 但 unique_lock 由于需要记录锁的状态(最后析构需要判断是否已经释放锁), 效率上会有损耗.

#include <bits/stdc++.h>

using namespace std;

std::shared_mutex mutex_;  //互斥对象

class ReadWriteMutex {
private:
    int value{0};
public:
    int read() const {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::shared_lock<std::shared_mutex> lock(mutex_);// shared_lock共享锁
        printf("value in read thread: %d\n", value);
        return value;
    }

    void write() {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::unique_lock<std::shared_mutex> lock(mutex_);// unique_lock独占锁
        value++;
        printf("value in write thread: %d\n", value);
    }
};


int main() {
    ReadWriteMutex readWriteMutex;
    constexpr int n = 10;
    thread tr[n];
    thread tw[n];

    for (int i = 0; i < n; ++i) {
        tr[i] = std::thread(&ReadWriteMutex::read, std::ref(readWriteMutex)); // 必须用std::ref完美转发
    }

    for (int i = 0; i < n; ++i) {
        tw[i] = std::thread(&ReadWriteMutex::write, std::ref(readWriteMutex));
    }

    for (int i = 0; i < n; ++i) {
        tr[i].join();
    }

    for (int i = 0; i < n; ++i) {
        tw[i].join();
    }

    return 0;
}

注意: mutex和hared_mutex锁不可重入, 前者会死锁, 后者抛异常

posted @ 2023-01-07 22:56  shmilyt  阅读(290)  评论(0编辑  收藏  举报