簡體   English   中英

當其他線程正在編寫線程安全時,我是否必須互斥讀取操作?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM