[英]std::lock_guard won't unlock
我正在尝试在以下代码中锁定互斥锁列表,以便一次只能有一个线程可以搜索,解锁,锁定或修改它。
#include <mutex>
#include <map>
#include <memory>
#include <vector>
#include <thread>
#include <atomic>
#include <iostream>
#include <Windows.h>
struct MoveableMutex
{
std::mutex m;
MoveableMutex() {}
MoveableMutex(MoveableMutex const&) {}
MoveableMutex& operator = (MoveableMutex const&) { return *this; }
};
class Locks
{
private:
static std::mutex map_lock;
static std::uint32_t lock_count;
std::map<std::uint32_t, MoveableMutex> locklist;
public:
std::uint32_t AddLock();
void RemoveLock(std::uint32_t ID);
void Lock(std::uint32_t ID);
bool TryLock(std::uint32_t ID);
void Unlock(std::uint32_t ID);
};
std::uint32_t Locks::lock_count = 0;
std::mutex Locks::map_lock;
std::uint32_t Locks::AddLock()
{
std::lock_guard<std::mutex> guard(map_lock);
locklist.insert(std::make_pair(++lock_count, MoveableMutex()));
return lock_count;
}
void Locks::RemoveLock(std::uint32_t ID)
{
std::lock_guard<std::mutex> guard(map_lock);
auto it = locklist.find(ID);
if (it != locklist.end())
{
it->second.m.unlock();
locklist.erase(it);
}
}
void Locks::Lock(std::uint32_t ID)
{
std::lock_guard<std::mutex> guard(map_lock);
auto it = this->locklist.find(ID);
if (it != this->locklist.end())
{
it->second.m.lock();
}
}
bool Locks::TryLock(std::uint32_t ID)
{
std::lock_guard<std::mutex> guard(map_lock);
auto it = this->locklist.find(ID);
if (it != this->locklist.end())
{
return it->second.m.try_lock();
}
return false;
}
void Locks::Unlock(std::uint32_t ID)
{
std::lock_guard<std::mutex> guard(map_lock);
auto it = this->locklist.find(ID);
if (it != locklist.end())
{
it->second.m.unlock();
}
}
int main()
{
Locks locklist;
int i = locklist.AddLock();
std::atomic<bool> stop(false);
std::atomic<bool> stop2(false);
std::thread o([&]
{
locklist.Lock(i);
while(!stop)
{
std::cout << "Hey\n";
Sleep(100);
}
locklist.Unlock(i);
});
std::thread t([&]
{
locklist.Lock(i);
while(!stop2)
{
std::cout << "Hey2\n";
Sleep(100);
}
locklist.Unlock(i);
});
Sleep(1000);
stop = true;
system("CLS");
o.join();
Sleep(1000);
stop2 = true;
t.join();
return 0;
}
但是,在Unlock
函数中使用std::lock_guard
,它将导致死锁。 如果我从“解锁”功能中删除了lock_guard,它将正常工作。
有没有原因lock_guard没有破坏或解锁?
一个线程调用Lock
,最终将互斥锁锁定在映射中。 另一个线程调用Lock
,它锁定map_lock
然后尝试将互斥锁锁定在地图中,并卡在那里(仍然保持map_lock
)。 最终,第一个线程退出循环并调用Unlock
,该线程在map_lock
上map_lock
。
这里的主要设计缺陷是,您的线程需要两个锁,一个接一个。 仅当所有线程以相同顺序获取它们(并以获取的相反顺序释放它们)时,这才安全地工作。 但是您的代码在不同的时间以不同的顺序获取它们:这是造成僵局的秘诀。
另请参阅: 锁定层次结构
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.