【问题标题】:Using atomic types in "wrapper" classes在“包装器”类中使用原子类型
【发布时间】:2019-06-10 01:15:36
【问题描述】:

我是 C++ 原子类型的新手,正在尝试将一些串行代码转换为多线程版本。

1) 我有几个类,它们基本上是机器类型的别名,但具有关联的函数和重载运算符,允许我将这些类型视为更复杂的东西,例如:

class myClass{
    atomic_ullong x;
public:
    void myClassFunc(atomic_ullong mask){x &= mask;}
    bool operator < (const myClass &in){ return (x & 0xFFFFFFFFFFFFFC00) <  (in.x & 0xFFFFFFFFFFFFFC00);}
};

将类成员和函数参数声明为它们的原子类型等价物,就像我上面所说的,就足够了吗?或者将 x 包装为“myClass”会迫使我开始使用互斥锁等?

2) 如果这可行,在某些情况下,我的代码会更复杂,并且有多个类成员。在这些情况下,如果这些成员都是基本的机器类型(int 等),我可以做同样的伎俩并保持原子类型的所有优点吗?

当然我可以在这里重构我的代码,但是显式类使它更简单,并且防止我意外地对存储的数据元素做一些我不应该做的事情。

这并不重要,但我在 Visual Studio 2008 中进行调试编译并在 GCC 中进行生产编译。我正在下载 VC2019,因为我们支持 C++11 和更高的支持。以前,我曾将 Boost 库用于多线程应用程序。

【问题讨论】:

  • 我不明白你在说什么。你会写什么样的 MT 代码?为什么还要麻烦原子?
  • 1) 也许,也许不是。原子数据类型本身不保证任何使用它们的代码将自动、100% 退款保证、线程安全。原子数据类型只是可用于实现线程安全代码的工具之一。有时使用它们可以消除对互斥体的需要。有时,出于其他原因,您仍然需要将互斥锁与原子对象一起使用。因此,您的其余问题都基于 1),并且由于无法回答 1),因此您的其余问题没有实际意义。
  • 专业提示:使用@curiousguy 通知用户您正在回复他们
  • 函数参数mask不需要是原子的。
  • 编写线程安全的代码并不是在现有代码上应用一些魔法尘埃。代码是线程安全的,因为它是设计的。使现有代码适应多线程应用程序意味着重新设计代码,然后重写它以匹配新设计。这比乍看起来要困难得多。

标签: c++ multithreading atomic


【解决方案1】:

如果你先读后写,那对于幼稚的操作来说不是原子的。

如果你写入两个原子值,这两个写在一起就不是原子的。

一般来说,获取数据并使每个基本类型原子化不会使您的代码在线程化后正确。它消除了竞争条件(在正式的 C++ 意义上,即 UB),但并没有使事情变得正确。

这就像通过将所有内容设为共享 ptr 来解决释放后的使用问题。当然,一个问题消失了,但这并不是最困难的部分。

在课堂上没有什么会导致原子中断。他们工作;它们并不能解决所有线程问题。

【讨论】:

    猜你喜欢
    • 2021-09-11
    • 2018-06-26
    • 1970-01-01
    • 2010-12-06
    • 2019-07-15
    • 2016-06-16
    • 1970-01-01
    • 2015-02-22
    • 2020-12-17
    相关资源
    最近更新 更多