首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用std::execution::par_unseq线程安全生成线程?

如何使用std::execution::par_unseq线程安全生成线程?
EN

Stack Overflow用户
提问于 2021-09-26 09:40:50
回答 1查看 462关注 0票数 1

我正在阅读C++并发操作。它说,当您使用std::execution::par时,您可以在每个内部元素使用互斥量,如下所示。

代码语言:javascript
复制
#include <mutex>
#include <vector>

class X {
  mutable std::mutex m;
  int data;

 public:
  X() : data(0) {}
  int get_value() const {
    std::lock_guard guard(m);
    return data;
  }
  void increment() {
    std::lock_guard guard(m);
    ++data;
  }
};

void increment_all(std::vector<X>& v) {
  std::for_each(v.begin(), v.end(), [](X& x) { x.increment(); });
}

但是它说,当您使用std::execution::par_unseq时,您必须用一个完整的容器互斥对象替换这个互斥对象,如下所示

代码语言:javascript
复制
#include <mutex>
#include <vector>

class Y {
  int data;

 public:
  Y() : data(0) {}
  int get_value() const { return data; }
  void increment() { ++data; }
};

class ProtectedY {
  std::mutex m;
  std::vector<Y> v;

 public:
  void lock() { m.lock(); }
  void unlock() { m.unlock(); }

  std::vector<Y>& get_vec() { return v; }
};

void incremental_all(ProtectedY& data) {
  std::lock_guard<ProtectedY> guard(data);
  auto& v = data.get_vec();
  std::for_each(std::execution::par_unseq, v.begin(), v.end(),
                [](Y& y) { y.increment(); });
}

但是即使使用第二个版本,并行算法线程中的y.increament()也有数据争用条件,因为并行算法线程之间没有锁。

如何使用std::execution::par_unseq的第二个版本是线程安全的?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-26 12:44:00

它仅是线程安全的,因为您不能访问并行算法中的共享数据。

唯一并行执行的是对y.increment()的调用。这些情况可以在任何顺序、任何线程上发生,并且可以任意交织在一起,甚至在单个线程内也是如此。但是y.increment()只访问y的私有数据,而且每个y都不同于所有其他向量元素。因此,这里没有数据竞赛的机会,因为各个元素之间没有“重叠”。

另一个不同的例子是,如果increment函数还访问在向量的所有不同元素之间共享的全局状态,那么情况就不同了。在这种情况下,现在存在数据竞争的可能性,因此需要同步对共享全局状态的访问。但是,由于并行未排序策略的特定需求,您不能只在这里使用互斥进行同步。

请注意,如果在并行算法的上下文中使用互斥对象,则可能会防止不同的危害:一种使用是使用互斥在执行for-each的不同线程之间进行同步。这适用于并行执行策略,但不适用于无顺序并行执行策略。这不是示例中的用例,因为在您的示例中没有共享数据,因此我们不需要任何同步。相反,在您的示例中,互斥体只同步for-每个线程对任何其他线程的调用,这些线程可能仍然作为更大应用程序的一部分运行,但是for-每个线程本身没有同步。这对于并行和并行都是有效的用例,但在后一种情况下,不能通过使用每个元素互斥来实现。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69333608

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档