在 C++ 中使用原子 TestAndSet 混合无锁和全锁线程同步

Mixing lock-less and lock-full thread synchronization with atomic TestAndSet in C++

我有一个消费者线程,它必须从缓冲区读取 而不锁定 。如果因为生产者线程正在写入缓冲区而必须跳过该操作,那也没关系。因此,在我看来,最合适的选择是在某些标志上使用 atomic TestAndSet

现在,前面提到的那些生产者线程也必须遵守此标志,因为它们无法在消费者正在读取缓冲区时开始写入缓冲区。我可以像下面的代码一样使用 atomic_flag::test_and_set 来解决这个问题:

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

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

flag.enter();

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

您不能混合搭配同步方法 - 双方必须同意。在我看来,您真正想要的是尝试获取锁,然后如果失败,则跳过。您可以在常规 std::mutex 上使用 try_lock 来实现此目的。

如果您希望生产者在 reader 正在读取时阻塞,则无锁是不可能的。

使用 std::mutex.

读者可以使用try_lock避免阻塞

作者(制作人)可以照常使用屏蔽lock功能

当然,为了避免锁泄漏,请使用std::unique_lock. Readers should pass std::try_to_lock as the second argument. You should then check owns_lock()查看数据是否可以安全读取或是否正在进行写入。