1

我有一个消费者线程,必须从缓冲区中读取而无需锁定。如果由于生产者线程正在写入缓冲区而必须跳过该操作,那很好。因此,在我看来,最合适的选择是某个标志上的原子 TestAndSet

现在,前面提到的生产者线程也必须尊重这个标志,因为当消费者正在读取缓冲区时,它们不能开始写入缓冲区。我可以使用 atomic_flag::test_and_set 来解决这个问题,如下代码:

while (flag.test_and_set()) 
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

...但是编写我自己的自旋锁似乎不太理想。我宁愿让我的线程休眠,直到它由于标志被清除而被唤醒。就像是:

flag.enter();

TLDR:如何最好地同步两个线程,一个可以锁定,另一个不能?

4

2 回答 2

4

使用std::mutex.

读者可以使用try_lock来避免阻塞。

作者(生产者)可以lock像往常一样使用阻塞功能。

当然,为了避免泄漏锁,请使用std::unique_lock. std::try_to_lock读者应该作为第二个参数传递。然后,您应该检查owns_lock()数据是否可以安全读取或是否正在进行写入。

于 2015-02-16T23:26:40.790 回答
1

您不能混合和匹配同步方法 - 双方必须同意。在我看来,您真正想要的是尝试获取锁,然后如果失败,请跳过。您可以定期使用try_lockstd::mutex来实现此目的。

如果您希望生产者在阅读器阅读时阻塞,那么无锁是不可能的。

于 2015-02-16T23:25:44.667 回答