关于写优先的Boost读写锁测试
介绍
读写锁是计算机编程中用于解决并发访问问题的同步原语。它允许多个线程同时读共享数据,但在写入数据时,只允许一个线程进行操作。而在各种读写锁实现中,读写优先策略的选择对系统的性能和公平性有很大的影响。本文通过一个简单的实验来测试boost库中的读写锁的优先策略。
测试代码
#include <boost/thread/shared_mutex.hpp>
#include <boost/thread/thread.hpp>
#include <iostream>
boost::shared_mutex rwlock;
void readFunc(const char* name) {
rwlock.lock_shared();
std::cout << name << " acquired read lock." << std::endl;
boost::this_thread::sleep(boost::posix_time::seconds(3));
rwlock.unlock_shared();
std::cout << name << " released read lock." << std::endl;
}
void writeFunc(const char* name) {
rwlock.lock();
std::cout << name << " acquired write lock." << std::endl;
boost::this_thread::sleep(boost::posix_time::seconds(3));
rwlock.unlock();
std::cout << name << " released write lock." << std::endl;
}
int main() {
boost::thread r1(readFunc, "Reader1");
boost::this_thread::sleep(boost::posix_time::seconds(1)); // Give Reader1 a head-start
boost::thread w(writeFunc, "Writer1");
boost::this_thread::sleep(boost::posix_time::seconds(4)); // Give Reader1 a head-start
boost::thread r2(readFunc, "Reader2");
boost::thread r3(readFunc, "Reader3");
boost::thread r4(readFunc, "Reader4");
boost::thread r5(readFunc, "Reader5");
boost::thread r6(readFunc, "Reader6");
boost::thread r7(readFunc, "Reader7");
boost::thread w2(writeFunc, "Writer2");
r2.join();
w.join();
r3.join();
r1.join();
w2.join();
r4.join();
r5.join();
r6.join();
r7.join();
return 0;
}
代码解析
我们利用了boost::shared_mutex
,其中共享锁用于读取,独占锁用于写入。
-
readFunc
函数模拟读取数据的操作。它首先获取共享锁,输出一个消息表示已经获取到读锁,然后睡眠3秒,最后释放锁。 -
writeFunc
函数模拟写入数据的操作。它首先获取独占锁,输出一个消息表示已经获取到写锁,然后同样睡眠3秒,最后释放锁。
在主函数中,我们创建了9个线程:7个读取线程和2个写入线程。通过控制线程的启动时间,我们试图模拟以下场景:
Reader1
首先开始,获取到读锁。- 在
Reader1
持有读锁的过程中,Writer1
尝试获取写锁。 - 当
Writer1
正在等待写锁时,Reader2
和Reader3......Reader7
尝试获取读锁。 - 在此期间,
Writer2
也尝试获取写锁。
测试结果
通过代码中的输出消息,我们可以观察到以下锁的获取和释放顺序:
-
Reader1 acquired read lock.
Reader1 released read lock.
Writer1 acquired write lock.
Writer1 released write lock.Reader6 acquired read lock.Reader3Reader5 acquired read lock.
acquired read lock.
Reader2 acquired read lock.
Reader4 acquired read lock.
Reader7 acquired read lock.
Reader3 released read lock.
Reader4 released read lock.
Reader5 released read lock.
Reader6 released read lock.
Reader7 released read lock.
Reader2 released read lock.
Writer2 acquired write lock.
Writer2 released write lock.
从上面的结果可以看出,尽管有读线程已经在等待,但写线程仍然优先获得了锁。这说明boost的读写锁实现是写优先的。
结论
Boost提供的shared_mutex
是一个写优先的读写锁。这种策略可能会导致读线程饥饿,但在某些场景下,这可以确保数据的即时性和写操作的优先级。
最后,当你在选择或设计一个并发系统时,了解并发原语的内部行为和性质是非常重要的,这样你才能做出明智的决策以满足你的需求。