这是一个有效的二进制互斥实现吗?

Is this a valid binary mutex implementation?

我不太确定这类问题是否会在这里遭到拒绝,但 当我有问题时我首先会来的地方,所以,我们开始了。

我有一个 std::vector<T> v 用来存储数据。在线程t1中,有一个数据生成器,可以随时插入数据。另一方面,在线程 t2 中,我需要在任意时间搜索 v 并从中访问和 return 一个元素。删除、交换等保证不会发生在v上,直到t1t2都加入主线程。

没有任何线程安全措施,代码以 SIGABRT 退出。我首先使用 std::mutexstd::lock_guard 并成功了,但是 lock/unlocks 的数量以百万计,我希望加快速度。所以我尝试实现以下系统:

#include <atomic>
#include <cassert>
#include <thread>

// Mutex-like thingy begin
class MyMutex
{
private:
  std::atomic<bool> modifyLockRequest;
  std::atomic<bool> accessLockRequest;
  std::atomic<bool> accessLock;

public:
  MyMutex() :
      modifyLockRequest(false),
      accessLockRequest(false),
      accessLock(false) {}

  void acquireModifyLock() {
    assert(!modifyLockRequest);
    modifyLockRequest = true;
    while( accessLockRequest && accessLock ) {
      std::this_thread::yield();
    }
  }

  void releaseModifyLock() {
    assert(modifyLockRequest);
    modifyLockRequest = false;
  }

  void acquireAccessLock() {
    assert(!accessLockRequest);
    accessLockRequest = true;
    while (modifyLockRequest) {
      std::this_thread::yield();
    }
    accessLock = true;
  }

  void releaseAccessLock() {
    assert(accessLockRequest);
    accessLock = false;
    accessLockRequest = false;
  }
};

MyMutex myMutex;

然后我用这个

myMutex.acquireModifyLock();
// Do insertion/deletion etc. on `v`
myMutex.releaseModifyLock();

myMutex.acquireAccessLock();
// Do stuff with `v[i]`
myMutex.releaseAccessLock();

我的理由是有 2 个布尔标志来警告任何线程试图获取锁,并有第三个标志来中断两个线程同时尝试获取锁的情况。

此代码似乎在 std::mutexstd::lock_guard 双人组的大约 1/8 时间运行良好,但是,我的问题是,此解决方案是否 得到保证总是 在我只有 2 个线程的情况下工作?

使用 std::atomic_flag 实现自旋锁在过去 3 个月内运行良好。此外,由于我的实现没有原子测试和设置机制,我会说,NO,它不是有效的(线程安全的)实现。感谢 Igor Tandetnik 的建议。