我正在寻找一个很好的C++读写器锁.我们有一个不常见的作家和许多常见读者的用例,并希望为此进行优化.我更喜欢跨平台的解决方案,但只有Windows可以接受.
较新版本的boost :: thread具有读/写锁(1.35.0及更高版本,显然以前的版本无法正常工作).
他们有名字shared_lock
,unique_lock
和,upgrade_lock
并在一个shared_mutex
.
使用标准的预测试,预先构建的东西总是很好(例如,Boost作为建议的另一个答案),但这是一个不太难以自己构建的东西.这是从我的一个项目中抽出的一个愚蠢的小实现:
#includestruct rwlock { pthread_mutex_t lock; pthread_cond_t read, write; unsigned readers, writers, read_waiters, write_waiters; }; void reader_lock(struct rwlock *self) { pthread_mutex_lock(&self->lock); if (self->writers || self->write_waiters) { self->read_waiters++; do pthread_cond_wait(&self->read, &self->lock); while (self->writers || self->write_waiters); self->read_waiters--; } self->readers++; pthread_mutex_unlock(&self->lock); } void reader_unlock(struct rwlock *self) { pthread_mutex_lock(&self->lock); self->readers--; if (self->write_waiters) pthread_cond_signal(&self->write); pthread_mutex_unlock(&self->lock); } void writer_lock(struct rwlock *self) { pthread_mutex_lock(&self->lock); if (self->readers || self->writers) { self->write_waiters++; do pthread_cond_wait(&self->write, &self->lock); while (self->readers || self->writers); self->write_waiters--; } self->writers = 1; pthread_mutex_unlock(&self->lock); } void writer_unlock(struct rwlock *self) { pthread_mutex_lock(&self->lock); self->writers = 0; if (self->write_waiters) pthread_cond_signal(&self->write); else if (self->read_waiters) pthread_cond_broadcast(&self->read); pthread_mutex_unlock(&self->lock); } void rwlock_init(struct rwlock *self) { self->readers = self->writers = self->read_waiters = self->write_waiters = 0; pthread_mutex_init(&self->lock, NULL); pthread_cond_init(&self->read, NULL); pthread_cond_init(&self->write, NULL); }
pthreads
并不是真正的Windows原生,但总体思路就在这里.这种实现略微偏向于作者(一大批作家可以无限期地挨饿); 只需修改writer_unlock
,如果你宁愿平衡是周围的其他方式.
是的,这是C而不是C++.翻译是留给读者的练习.
Greg Rogers指出POSIX标准确实指明了pthread_rwlock_*
.如果你没有pthreads
,这没有任何帮助,但它激起了我的记忆:Pthreads-w32应该工作!而不是将此代码移植到非pthreads
自己使用,只需在Windows上使用Pthreads-w32,pthreads
在其他地方使用本机.
您可以使用boost来创建读写锁:
#includetypedef std::shared_mutex Lock; typedef std::unique_lock< Lock > WriteLock; typedef std::shared_lock< Lock > ReadLock; Lock myLock; void ReadFunction() { ReadLock r_lock(myLock); //Do reader stuff } void WriteFunction() { WriteLock w_lock(myLock); //Do writer stuff }
无论您决定使用什么,都要将工作负载与简单锁定进行对比,因为当没有争用时,读/写锁的速度往往比简单的互斥锁慢3-40倍.
这里有一些参考
编辑:MSDN Magazine链接不再可用.CodeProject的文章现在可以在https://www.codeproject.com/Articles/32685/Testing-reader-writer-locks上找到并总结得非常好.我还找到了一个关于复合同步对象的新MSDN链接.
有一篇关于MSDN上的读写器锁的文章介绍了它们的一些实现.它还介绍了Slim读/写锁,这是Vista引入的内核同步原语.还有一篇关于比较不同实现(包括MSDN文章的实现)的CodeProject文章.
C ++ 17支持std::shared_mutex
。MSVC ++ 2015和2017 支持该功能。