C++ 新旧版本两种读写锁

一、简介

读写锁(Read-Write Lock)是一种并发控制机制,用于多线程环境中实现对共享资源的高效读写操作。读写锁允许多个线程同时读取共享资源,但在有写操作时,需要互斥地独占对共享资源的访问,以确保数据的一致性。

二、shared_mutex

std::shared_mutex 是 C++17 引入的,用于实现共享/独占访问控制,以下是简单示例:

#include <iostream>
#include <thread>
#include <shared_mutex>

std::shared_mutex rwLock;
int sharedData = 0;  // 共享资源

void readerFunction(int id) {
    while (true) {
        rwLock.lock_shared();
        std::cout << "Reader " << id << " reads sharedData: " << sharedData << std::endl;
        rwLock.unlock_shared();
        // 模拟一些耗时操作
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }
}

void writerFunction(int id) {
    while (true) {
        rwLock.lock();
        sharedData++;
        std::cout << "Writer " << id << " writes sharedData: " << sharedData << std::endl;
        rwLock.unlock();
        // 模拟一些耗时操作
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
}

int main() {
    const int numReaders = 3;
    const int numWriters = 3;
    std::thread readers[numReaders];
    std::thread writers[numWriters];
    // 启动线程
    for (int i = 0; i < numReaders; i++) {
        readers[i] = std::thread(readerFunction, i);
    }
    for (int i = 0; i < numWriters; i++) {
        writers[i] = std::thread(writerFunction, i);
    }
    // Join线程
    for (int i = 0; i < numReaders; i++) {
        readers[i].join();
    }
    for (int i = 0; i < numWriters; i++) {
        writers[i].join();
    }
    return 0;
}

三、自定义 ReadWriteLock

C++17前可以通过 mutexcondition_variable 实现一个自定义的读写锁。代码如下:

#include <mutex>
#include <condition_variable>

class ReadWriteLock {
public:
    ReadWriteLock() : readersCount(0), writing(false) {}

    void lockRead() {
        std::unique_lock<std::mutex> lock(mutex_);
        readCondition_.wait(lock, [this] { return !writing; });
        readersCount++;
    }

    void unlockRead() {
        std::unique_lock<std::mutex> lock(mutex_);
        readersCount--;
        if (readersCount == 0) {
            writeCondition_.notify_one();
        }
    }

    void lockWrite() {
        std::unique_lock<std::mutex> lock(mutex_);
        writeCondition_.wait(lock, [this] { return readersCount == 0 && !writing; });
        writing = true;
    }

    void unlockWrite() {
        std::unique_lock<std::mutex> lock(mutex_);
        writing = false;
        readCondition_.notify_all();
        writeCondition_.notify_one();
    }

private:
    std::mutex mutex_;
    std::condition_variable readCondition_;
    std::condition_variable writeCondition_;
    int readersCount;
    bool writing;
};

使用示例:

#include <iostream>
#include <thread>
#include "ReadWriteLock.hpp" // 包含上面ReadWriteLock的头文件

int sharedData = 0;  // 共享数据
ReadWriteLock rwLock;

void readerFunction(int id) {
    while (true) {
        rwLock.lockRead();
		std::cout << "Reader " << id << " reads sharedData: " << sharedData << std::endl;
        rwLock.unlockRead();
        // 模拟一些耗时操作
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }
}

void writerFunction(int id) {
    while (true) {
        rwLock.lockWrite();
        sharedData++;
        std::cout << "Writer " << id << " writes sharedData: " << sharedData << std::endl;
        rwLock.unlockWrite();
        // 模拟一些耗时操作
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
}

int main() {
    const int numReaders = 3;
    const int numWriters = 3;
    std::thread readers[numReaders];
    std::thread writers[numWriters];
    // 启动线程
    for (int i = 0; i < numReaders; i++) {
        readers[i] = std::thread(readerFunction, i);
    }
    for (int i = 0; i < numWriters; i++) {
        writers[i] = std::thread(writerFunction, i);
    }
    // Join线程
    for (int i = 0; i < numReaders; i++) {
        readers[i].join();
    }
    for (int i = 0; i < numWriters; i++) {
        writers[i].join();
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C11标准库中提供了读写锁,可以用来实现多个线程对同一资源的并发读写操作。下面是使用读写锁的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <threads.h> int data = 0; rwlock_t lock; int reader(void* arg) { int id = *(int*)arg; while (1) { thrd_sleep((struct timespec){.tv_sec = 1}, NULL); // 模拟读操作 // 加读锁 rwlock_rdlock(&lock); printf("Reader %d read data: %d\n", id, data); // 释放读锁 rwlock_unlock(&lock); } return 0; } int writer(void* arg) { int id = *(int*)arg; while (1) { thrd_sleep((struct timespec){.tv_sec = 2}, NULL); // 模拟写操作 // 加写锁 rwlock_wrlock(&lock); data++; printf("Writer %d write data: %d\n", id, data); // 释放写锁 rwlock_unlock(&lock); } return 0; } int main(int argc, char const *argv[]) { // 初始化读写锁 rwlock_init(&lock); // 创建3个读线程 thrd_t readers[3]; int readerIds[3]; for (int i = 0; i < 3; i++) { readerIds[i] = i + 1; thrd_create(&readers[i], reader, &readerIds[i]); } // 创建2个写线程 thrd_t writers[2]; int writerIds[2]; for (int i = 0; i < 2; i++) { writerIds[i] = i + 1; thrd_create(&writers[i], writer, &writerIds[i]); } // 等待所有线程结束 for (int i = 0; i < 3; i++) { thrd_join(readers[i], NULL); } for (int i = 0; i < 2; i++) { thrd_join(writers[i], NULL); } // 销毁读写锁 rwlock_destroy(&lock); return 0; } ``` 这个示例程序中有3个读线程和2个写线程,读线程每隔1秒钟读一次共享变量data的值,写线程每隔2秒钟写一次共享变量data的值。读线程和写线程之间会相互竞争读写锁,以实现对共享变量的并发访问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值