【问题标题】:Is possible to use std::deque::push_back() and std::deque::front()/std::deque::pop_front() on different threads without synchronization? [duplicate]是否可以在不同步的情况下在不同的线程上使用 std::deque::push_back() 和 std::deque::front()/std::deque::pop_front() ? [复制]
【发布时间】:2014-04-09 16:35:23
【问题描述】:

我有一个生产者/消费者的情况,一个生产者和一个消费者,共享一个共同的 std::deque。

让我写一些代码:

deque<int> dq;

void producer()
{
for (int i = 0; i < N; i++)
   dq.push_back(i);
   // signal data
}

void consumer()
{
  // get signal
  int n = dq.front();
  dq.pop_front();
}

考虑在独立线程上执行的 consumer() 和 producer()。这段代码需要同步吗?

【问题讨论】:

标签: c++ multithreading stl


【解决方案1】:

如果您没有在读取器和写入器之间进行同步,则可能会损坏数据。

所以一般来说答案是否定的。

requote

多个阅读器是安全的。多个线程可以同时读取 单个容器的内容,这将正常工作。 自然,不能有任何作家对容器进行操作 在读取期间。

根据环境,可以使用不同的并发容器。例如,MSDN 支持concurrent queue 并且有boost 库也提供lock free containers

【讨论】:

    【解决方案2】:

    通常,,您的代码不是线程安全的。

    请参阅MSVC 的相关文档(“C++ 标准库中的线程安全”):

    如果单个对象正在由一个线程写入,则所有读取 并且必须在相同或其他线程上写入该对象 受保护。例如,给定一个对象 A,如果线程 1 正在写入 A,那么必须阻止线程 2 读取或写入 A。

    或者对于GCC(“并发>容器”)

    [...] 锁定必须几乎总是在容器外部完成,通过 客户端代码(是你,不是我们)。

    C++ 标准(甚至是 C++11 标准)在此处不强制要求线程安全访问。如果您使用其他编译器,它的文档肯定会告诉您有关并发访问容器类的类似信息。

    【讨论】:

    • 但是对于特别是双端队列,使用指向元素值的原始指针(不是迭代器)读取双端队列的前端元素,同时从另一个线程推回不是安全的吗? “ push_back 的迭代器有效性:与此容器相关的所有迭代器都无效。指向容器中元素的指针和引用仍然有效,指的是它们在调用之前引用的相同元素。” cplusplus.com/reference/deque/deque/push_back
    猜你喜欢
    • 1970-01-01
    • 2015-01-15
    • 1970-01-01
    • 2011-05-05
    • 2015-01-05
    • 2021-09-30
    • 2010-12-23
    • 1970-01-01
    • 2017-12-19
    相关资源
    最近更新 更多