其他线程正在写线程安全时,我是否必须互斥读取操作?

在特定的多线程情况下,我感到困惑,无法找到对此情况的明确解释。在下面的代码中,两个自定义线程正在安全地编写+读取线程,但主线程也正在同时读取。所以这是我的问题:我也必须互斥读取功能吗?还是绝对不可能使应用程序崩溃,例如可能是由于矢量中先前删除的指针引起的?希望你们能帮助我,谢谢!

#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';

}
yuanlei99 回答:其他线程正在写线程安全时,我是否必须互斥读取操作?

std::thread执行线程和原始main执行线程都在调用同一std::vector对象的各种方法。

std::vector的方法(或任何C ++库容器的方法)都不是线程安全的,因此必须对所有执行线程对它们的所有访问进行排序(即由互斥锁保护)。载体的内容是否被修改无关紧要。 begin()不是线程安全的。句号等等...

resize()增加了伤害,使所有现有的迭代器对std::vector的内容无效,因此resize()中的任何一个执行的std::thread将立即生效使所有迭代器都无效,其他线程正在使用同一std::vector对象;因此必须对整个事物进行排序/锁定。

TL; DR:您必须使用互斥体才能访问std::vector。向量的内容是否由特定的执行线程修改是无关紧要的。

P.S。 std::vector方法不是线程安全的问题独立于向量中所有内容的线程安全。如果您已经准备好向量内容的所有迭代器,并开始使用多个执行线程中的现有迭代器来处理向量中的内容:是否需要排序取决于向量中内容的固有性质,以及它的线程-安全要求。

本文链接:https://www.f2er.com/3169635.html

大家都在问