c++ - 这是一个有效的二进制互斥锁实现吗?
问题描述
我不确定这类问题在这里是否不受欢迎,但是当我有问题时,这是我第一个来的地方,所以,我们开始吧。
我有一个std::vector<T> v
用来存储数据的。在 threadt1
中,有一个数据生成器,可以随时进行数据插入。另一方面,在 threadt2
中,我需要在任意时间搜索v
和访问并从中返回一个元素。删除、交换等保证不会发生,v
直到两者都t1
加入t2
主线程。
如果没有任何线程安全措施,代码将以SIGABRT
. 我第一次使用std::mutex
并std::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::mutex
和std::lock_guard
duo 中运行良好,但是,我的问题是,这个解决方案是否保证在我只有 2 个线程的情况下始终有效?
解决方案
std::atomic_flag
在过去的 3 个月里,用来实现自旋锁的效果很好。此外,由于我的实现没有原子测试和设置机制,我会说,不,它不是一个有效的(线程安全的)实现。感谢 Igor Tandetnik 的建议。
推荐阅读
- javascript - 在标记检测 A 帧 AR.JS 上播放音频
- elasticsearch - 减少 ElasticSearch 返回的数据
- angular - ngx-translate:翻译 html 中的字符串
- javascript - JavaScript 代码似乎跳过了对另一个函数的回调
- c# - 获取原始日期时间偏移量
- python - 如何在 Python 中压缩和加密文本流
- powerbi - DAX 自定义总计未按预期运行
- javascript - 在 Angular 中确定特定区域是否折叠
- javascript - 使用 jQuery 追加时重复输入
- windows - 制作可启动的 USB 程序安装程序