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

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

本文关键字:同步 线程 混合 TestAndSet C++      更新时间:2023-10-16

我有一个使用者线程,它必须从缓冲区中读取而不锁定。如果由于生产者线程正在向缓冲区写入内容而必须跳过操作,那也没关系。因此,在我看来,最合适的选择似乎是在某个标志上使用原子TestAndSet

现在,前面提到的生产者线程也必须尊重这个标志,因为当消费者从缓冲区读取时,它们不能开始向缓冲区写入

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

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

flag.enter();

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

使用std::mutex

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

编写器(生产者)可以像往常一样使用阻塞lock函数。

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

您不能混合和匹配同步方法-双方必须达成一致。在我看来,你真正想要的是尝试获取锁,如果它失败了,就跳过。您可以在常规std::mutex上使用try_lock来实现这一点。

如果你想让生产者在读者阅读时屏蔽,那么无锁定是不可能的。