当前位置:  开发笔记 > 编程语言 > 正文

读者/作者用C++锁定

如何解决《读者/作者用C++锁定》经验,为你挑选了6个好方法。

我正在寻找一个很好的C++读写器锁.我们有一个不常见的作家和许多常见读者的用例,并希望为此进行优化.我更喜欢跨平台的解决方案,但只有Windows可以接受.



1> Greg Rogers..:

较新版本的boost :: thread具有读/写锁(1.35.0及更高版本,显然以前的版本无法正常工作).

他们有名字shared_lock,unique_lock和,upgrade_lock并在一个shared_mutex.


我们在1.34.1,这可能是提升的理由:)

2> ephemient..:

使用标准的预测试,预先构建的东西总是很好(例如,Boost作为建议的另一个答案),但这是一个不太难以自己构建的东西.这是从我的一个项目中抽出的一个愚蠢的小实现:

#include 

struct 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在其他地方使用本机.


我很好奇你为什么在pthread_mutex_t上重新实现pthread_rwlock_(rd/wr)(un)锁而不是仅使用原生pthread API.
在reader_unlock函数中,即使读者当前正在读取数据,也会向编写者发出信号.最好添加你的条件if(self-> readers == 0 && self-> write_waiters)...
什么意思没有意义?即使有读者等待锁定,只要没有人实际持有锁定,并且继续做工作,新作家也可以愉快地取得锁定.如果你有一个连续的读者流,并且不希望偶尔的短作家被他们阻止,这是更好的平衡.

3> Yochai Timme..:

您可以使用boost来创建读写锁:

#include 

typedef 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
}



4> ididak..:

无论您决定使用什么,都要将工作负载与简单锁定进行对比,因为当没有争用时,读/写锁的速度往往比简单的互斥锁慢3-40倍.

这里有一些参考



5> vividos..:

编辑:MSDN Magazine链接不再可用.CodeProject的文章现在可以在https://www.codeproject.com/Articles/32685/Testing-reader-writer-locks上找到并总结得非常好.我还找到了一个关于复合同步对象的新MSDN链接.

有一篇关于MSDN上的读写器锁的文章介绍了它们的一些实现.它还介绍了Slim读/写锁,这是Vista引入的内核同步原语.还有一篇关于比较不同实现(包括MSDN文章的实现)的CodeProject文章.



6> Serge Rogatc..:

C ++ 17支持std::shared_mutex。MSVC ++ 2015和2017 支持该功能。

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有