C++11读写锁的实现

参考的源码

读写锁,一直都有听,也大概知道点原理,一直没有探究内部是如何实现的,正好今天完成了几项大作业,研究一下读写锁实现的原理。

读写锁的原理就是,可以多次读,但是写只能一次一次的写入,我参考的源码博主控制了写优先,并且读的优先级没我写的这么高。我自己在修改了他的源码,实现的是读优先,并且优先级很高,如果存在大量的读操作,可能会出现写操作线程饥饿的现象。如果在具体的场景中写操作也多,可以修改wait条件来判断优先级。我最近的感悟,如果非必要,一个类的对象不必非要跨线程操作。对象不跨线程操作,也就不涉及这种饥饿问题了


#include<mutex>
#include<condition_variable>
#include<iostream>
#include<vector>
#include<thread>

using namespace std;

class ReadWriteLock {
private:
	int readWaiting = 0;  //等待读
	int writeWaiting = 0; //等待写
	int reading = 0; //正在读
	int writing = 0;  //正在写
	std::mutex mx;
	std::condition_variable cond;
	bool preferWriter;  //偏向读
public:
	ReadWriteLock(bool isPreferWriter = false) :preferWriter(isPreferWriter) {}

	void readLock() {
		std::unique_lock<std::mutex>lock(mx);
		++readWaiting;
        // preferWriter靠这个来让写锁优先了
		//cond.wait(lock, [&]() {return writing <= 0 && (!preferWriter || writeWaiting <= 0); });
        // 读锁优先
        cond.wait(lock,[&](){return writing <= 0;});
    	++reading;
		--readWaiting;
	}

	void writeLock() {
		std::unique_lock<std::mutex>lock(mx);
		++writeWaiting;
        // 这里规定writing<=0才能继续执行,保证了写的时候进入一次,reading <= 0 保证了读的优先
		cond.wait(lock, [&]() {return readWaiting <=0 && reading <= 0 && writing <= 0; });
		++writing;
		--writeWaiting;
	}

	void readUnLock() {
		std::unique_lock<std::mutex>lock(mx);
		--reading;
		//当前没有读者时,唤醒一个写者
		if(reading<=0)
			cond.notify_one();  
	}

	void writeUnLock() {
		std::unique_lock<std::mutex>lock(mx);
		--writing;
		//唤醒所有读者、写者
		cond.notify_all(); 
	}
};


//true 为写者优先,不过我修改了源码,true或者false都没有意义了
ReadWriteLock readWriteLock(false);

// 锁都是要等三秒钟才释放锁
void reader() {
	readWriteLock.readLock();
	cout << "reader" << endl;
	this_thread::sleep_for(std::chrono::seconds(3));
	readWriteLock.readUnLock();
}

void writer() {
	readWriteLock.writeLock();
	cout << "writer" << endl;
	this_thread::sleep_for(std::chrono::seconds(3));
	readWriteLock.writeUnLock();
}

int main() {
	vector<thread>vec;
	for (int i = 0; i < 5; ++i) {
		vec.push_back(thread(reader));
		vec.push_back(thread(writer));
	}
	for (int i = 0; i < vec.size(); ++i) {
		if(vec[i].joinable())
			vec[i].join();
	}
}


  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值