有关通过 std::atomic_flag 实现自旋锁互斥锁的问题

问题描述 投票:0回答:1

我目前正在阅读一本名为《C++ concurrency in action》的书。有一个自旋锁互斥实现的例子:

class spinlock_mutex
{
 std::atomic_flag flag;
public:
 spinlock_mutex():
 flag(ATOMIC_FLAG_INIT)
 {}
 void lock()
 {
   while(flag.test_and_set(std::memory_order_acquire));
 }
 void unlock()
 {
   flag.clear(std::memory_order_release);
 }
};

我在这个示例中遇到的第一个问题是, std::atomic_flag 的operator=被删除,并且它无法编译。但是如果我删除 ctor,并在私有类部分中执行此指令,一切都很好,没有错误:

std::atomic_flag flag = ATOMIC_FLAG_INIT
为什么会编译?这不是和这里使用的operator=一样吗?

我想问的第二件事是,循环过程实际上是如何进行的?

如果我创建:

spinlock_mutex mtx;
mtx.lock();

//some code

mtx.unlock();

并尝试在方法的锁 while 循环内打印一些调试:

void lock()
{
  while (flag.test_and_set(std::memory_order_acquire)) {
    std::cout << "here" << "\n";
  }
}

它没有打印任何东西,所以看起来它没有进入内部,那么我们如何实现循环呢?

我已经描述了 2 个问题以及我在上面尝试过的方法。

c++ multithreading c++11 mutex spinlock
1个回答
0
投票
  1. 听起来你把

    operator=
    误认为是复制初始化。
    std::atomic_flag::operator=
    确实被删除了,但是
    std::atomic_flag flag = ATOMIC_FLAG_INIT
    没有使用赋值运算符。 它使用标志的构造函数。

  2. 如果标志最初未锁定,则不会打印任何内容。 您需要一些争用,即您需要两个单独的线程尝试同时锁定互斥体。 如果不进入

    while
    循环,说明锁定成功,无需等待。

© www.soinside.com 2019 - 2024. All rights reserved.