首页 > 解决方案 > 这是一个有效的二进制互斥锁实现吗?

问题描述

我不确定这类问题在这里是否不受欢迎,但是当我有问题时,这是我第一个来的地方,所以,我们开始吧。

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

如果没有任何线程安全措施,代码将以SIGABRT. 我第一次使用std::mutexstd::lock_guard成功了,但是锁定/解锁的数量以百万计,我希望加快速度。所以我尝试实现以下系统:

#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 个布尔标志来提醒任何线程试图获得锁,并有第三个标志来中断两个线程同时尝试获得锁的情况。

这段代码似乎在大约 1/8 次std::mutexstd::lock_guardduo 中运行良好,但是,我的问题是,这个解决方案是否保证在我只有 2 个线程的情况下始终有效?

标签: c++multithreadingc++11mutex

解决方案


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


推荐阅读