当前位置: 首页 > 知识库问答 >
问题:

std::vector自然线程安全迭代

臧友樵
2023-03-14

假设我有std::vector和两个线程。

第一个线程正在处理擦除函数,而第二个线程在for循环中

这种情况是线程安全的吗?

第二个线程会继续运行还是抛出异常?

#include <iostream>
#include <vector>
#include <thread>

int main()
{
    std::vector<int> intContainer;

    for ( int index = 0; index <= 100000; ++index){
        intContainer.push_back(index);
    }

    std::thread t1([&](){
        while ( 1 ){
            intContainer.erase( std::find(intContainer.begin(), intContainer.end(), random(1, 100000) ) );
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
        }
    });

    std::thread t2([&] (){
        for ( auto& val : intContainer ){
            std::cout << val << std::endl;
        }   
    });

    t1.join();
    t2.join();

    return 0;
}

共有1个答案

李谦
2023-03-14

这是线程不安全的,但也是未定义的行为。

它是线程不安全的,因为您在迭代它时正在更改元素(以及向量本身)。

这是一种未定义的行为,因为上面提到过(竞争),但也因为您基本上是在擦除向量中的任何位置的元素,这意味着您实际上是在使它的所有迭代器无效(用于在另一个线程中迭代)。因此,即使这是一个单线程程序(例如使用光纤),您仍然可以使用UB。

请注意,不会抛出异常,因为某些内容不是线程安全的。当然,这并不意味着错误(无论是腐败、崩溃等)不会发生——它们肯定会发生。

此外,请注意,线程(两者都不是)也将停止运行。他们会继续,却不知道他们把一切都搞砸了。关键是他们没有办法知道。

 类似资料:
  • 问题内容: 在javadoc中,ConcurrentHashMap如下: 检索操作(包括get)通常不会阻塞,因此可能与更新操作(包括put和remove)重叠。检索反映了自启动以来最新完成的更新操作的结果。对于诸如putAll和clear的聚合操作,并发检索可能仅反映某些条目的插入或删除。同样,迭代器和枚举返回的元素反映了在创建迭代器/枚举时或此后某个时刻哈希表的状态。他们不抛出Concurre

  • 下面的代码显示了我要做的:

  • 我只是想探讨一下ThreadSafe是什么意思? 以下是我的理解: 对我来说,它看起来像;允许多个线程同时访问一个集合;这与它的同步无关。例如,任何没有同步关键字的方法;是线程安全的,意味着多个线程可以访问它。 由开发人员选择在此方法上维护更多逻辑(同步),以便在多线程访问数据时保持数据完整性。这与线程安全是分开的。 如果我的上述陈述是错误的;只需阅读下面的 JAVA DOC for 'Concu

  • 我在std::sort中发现了一个bug,特别是在一些QuickSort的实现中,我不知道问题是否出在一般的算法中。 精华: 当元素小于16时,所有的规范都被替换,因为std::sort使用插入排序。 当有17个或更多的元素时,使用快速排序,并从元素数量的对数限制递归深度,但向量在第一次__introsort_loop迭代时有时间恶化。 当有许多相同的元素时,就会出现向量损坏。用无效迭代器替换有效

  • 错误:无法将类型为“std::_bit_reference&”的非常量lvalue引用绑定到类型为“std::vector::reference”{aka“std::_bit_reference”}的rvalue 因此,它抱怨,因为只有第二个参数是rvalue

  • 问题内容: HttpUrlConnection线程安全吗?即,如果我有一个连接到服务器的HttpConnection实例,并且该实例被不同的线程使用(例如,尝试同时发送POST),HttpUrlConnection将如何处理这种情况?a)他们将串行发送POST,还是b)第一个线程发送POST,获取响应,然后第二个线程发送POST?如果它们以串行方式发送POST,则意味着到同一tcp连接的多个活动P