[英]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.