[英]Is std::mutex as a member variable thread-safe for multiple threads?
[英]Do i have to mutex a reading operation while other threads are writing thread safe?
我在特定的多線程情況下感到困惑,無法找到這種情況的明確解釋。 在下面的代碼中,兩個自定義線程是寫+讀線程安全的,但主線程也在同時讀取。 所以這是我的問題:我是否也必須對讀取的 function 進行互斥? 還是絕對不可能使應用程序崩潰,例如向量中先前刪除的指針的原因? 我希望你們能幫助我,謝謝!
#include <thread>
#include <mutex>
#include <iostream>
#include <vector>
int g_i = 0;
std::vector<int> test;
std::mutex g_i_mutex; // protects g_i
void safe_increment()
{
std::lock_guard<std::mutex> lock(g_i_mutex);
++g_i;
test.resize(test.size() + 1, 2);
std::cout << std::this_thread::get_id() << ": " << g_i << '\n';
for (std::vector<int>::const_iterator i = test.begin(); i != test.end(); ++i)
std::cout << std::this_thread::get_id() << " thread vector: " << *i << '\n';
// g_i_mutex is automatically released when lock
// goes out of scope
}
void request_threadedvar()
{
for (std::vector<int>::const_iterator i = test.begin(); i != test.end(); ++i)
std::cout << std::this_thread::get_id() << " request threaded vector: " << *i << '\n';
}
int main()
{
std::cout << "main: " << g_i << '\n';
test.resize(test.size() + 1, 1);
for (std::vector<int>::const_iterator i = test.begin(); i != test.end(); ++i)
std::cout << "main vector: " << *i << '\n';
std::thread t1(safe_increment);
request_threadedvar();
std::thread t2(safe_increment);
t1.join();
t2.join();
std::cout << "main: " << g_i << '\n';
for (std::vector<int>::const_iterator i = test.begin(); i != test.end(); ++i)
std::cout << "main vector: " << *i << '\n';
}
std::thread
執行線程以及原始main
執行線程都在調用相同std::vector
object 的各種方法。
std::vector
的方法(或任何 C++ 庫容器的方法)都不是線程安全的,因此所有執行線程對它們的所有訪問都必須按順序排列(即受互斥體保護)。 向量的內容是否被修改並不重要。 begin()
不是線程安全的。 句號。 ETC...
雪上加霜的是, resize()
使所有現有迭代器對std::vector
的內容無效,因此由任何std::thread
執行的resize()
將立即使相同std::vector
的所有迭代器失效std::vector
object 正在被其他線程使用; 因此,必須對整個事情進行排序/鎖定。
TL;DR:您必須使用互斥鎖來訪問std::vector
。 向量的內容是否被特定的執行線程修改是無關緊要的。
PS std::vector
方法不是線程安全的問題與向量中任何內容的線程安全無關。 如果您已經准備好向量內容的所有迭代器,並開始使用多個執行線程中的現有迭代器對向量中的內容進行處理:是否需要排序取決於向量中任何內容的固有性質及其線程-安全要求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.