此代碼段中是否存在任何潛在問題?
#include <mutex>
#include <map>
#include <vector>
#include <thread>
constexpr int FOO_NUM = 5;
int main()
{
std::map<int, std::mutex> mp;
std::vector<std::thread> vec;
for(int i=0; i<2; i )
{
vec.push_back(std::thread([&mp](){
std::lock_guard<std::mutex> lk(mp[FOO_NUM]); //I think there is some potential problem here, am I right?
//do something
}));
}
for(auto& thread:vec)
{
thread.join();
}
根據檔案,它說:
如果鍵不存在,則插入 value_type(key, T())。這個函式相當于 return insert(std::make_pair(key, T())).first->second;
我認為上述代碼片段中存在潛在問題。您會看到這可能會發生:
1.第一個執行緒創建了一個mutex
,并且正在鎖定mutex
.
2.第二個執行緒創建了一個新的,mutex
第一個執行緒中創建的需要銷毀,而它仍然在第一個執行緒中使用。
uj5u.com熱心網友回復:
是的,有一場資料競賽,但它更為根本。
無論如何,C 庫中的容器都不是執行緒安全的。他們的運算子都不是執行緒安全的。
mp[FOO_NUM]
在所示代碼中,多個執行執行緒呼叫 map 的[]
運算子。這不是執行緒安全的,運算子本身。地圖中包含的內容無關緊要。
第二個執行緒創建了一個新執行緒,并且在第一個執行緒中創建的互斥體需要在第一個執行緒中使用時被銷毀。
在顯示的代碼中,唯一破壞任何互斥鎖的是地圖的解構式,當地圖本身在從main()
.
std::lock_guard<std::mutex>
當然,當被銷毀并釋放互斥鎖時,它不會破壞其互斥鎖。std::lock_guard
執行執行緒對映射[]
運算子的呼叫可能會默認構造一個 new std::mutex
,但是當執行執行緒加入時,沒有什么會破壞它。a 中的默認構造值std::map
,由它的[]
運算子,只有在某些東西明確地破壞它時才會被破壞。
并且[]
運算子本身不是執行緒安全的,它與互斥體的構造或破壞無關。
uj5u.com熱心網友回復:
operator[]
如果在多個執行緒中沒有同步的情況下呼叫關聯容器和無序容器,則未指定它們可以避免資料爭用。請參閱[container.requirements.dataraces]/1。
因此,您的代碼存在資料競爭,因此存在未定義的行為。是否創建新的互斥鎖也無關緊要。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/455163.html
上一篇:減少記憶體對齊