5

我们已经实现了一个读写器锁

 typedef boost::unique_lock<boost::shared_mutex> WriterLock;
 typedef boost::shared_lock<boost::shared_mutex> ReadersLock;

我们有许多多线程阅读器,而编写器只有几个。读取器与其他读取器共享访问权限,但阻止写入器。Writer 阻塞,直到它拥有对资源的独占访问权。

我们在 boost 文档中找不到这个......防止 Writer 饥饿的政策是什么?
例如,如果有很多读者都从一个线程池中敲锁,那么在作者最终获得锁之前,是否有任何保证尝试锁的次数上限?

我们看到的性能数据似乎表明写入必须等到根本没有读者,并且在极少数情况下这是很长时间,因为新读者可以在当前读者正在接受服务时请求锁定。在这种情况下,在我们的代码中,作者似乎必须等待很长时间,直到根本没有读取。

我们更喜欢类似队列的系统,当写入者请求锁定时,所有当前的读取器都会耗尽,但所有新进入的读取器都会阻塞在写入器请求之后。

Boost 中可升级锁概念的行为是什么? 提升线程

它没有说明它如何处理作家饥饿。

4

3 回答 3

1

@Guerrero 解决方案的一个小改进,增加了多个读者和多个作者的公平性,因此没有人会饿死:

read() {
    while (atomic-write-requests > 0)
        condition.wait();
    ReadersLock lock(acquireReaderLock());
    doRead();
}
write() {
    while (atomic-write-requests > 0)
        condition.wait();
    atomic-write-requests++;
    WritersLock lock(acquireWriterLock());

    doWrite();
    atomic-write-requests--;
    condition.notify();
}

在这个解决方案中,每当作者离开范围时,就会开始一场新的公平竞争。

于 2015-11-17T09:02:07.667 回答
0

如果您想要的是一种先进先出方法,boost 在其状态图库上实现了几种调度策略(包括 FIFO)。我猜你将不得不调整你的很多代码来使用它。查看有关 fifo_scheduler 和 FifoWorker 的文档:

http://www.boost.org/doc/libs/1_51_0/libs/statechart/doc/reference.html#FifoWorker

http://www.boost.org/doc/libs/1_51_0/libs/statechart/doc/reference.html#fifo_scheduler.hpp

于 2012-10-25T20:45:13.023 回答
0

在不了解 boost 实现的情况下,也许您可​​以通过实现来防止 writer 饿死。当作家存在时,读者可以等待。也许像这样的伪代码:

read() {
    while (atomic-write-requests > 0) {
        condition.wait();
    }
    ReadersLock lock(acquireReaderLock());
    doRead();
}
write() {
    atomic-write-requests++;
    WritersLock lock(acquireWriterLock());

    doWrite();
    atomic-write-requests--;
    condition.notify();
}
于 2012-10-25T20:35:10.323 回答