首页 > 代码库 > 原子类型

原子类型

http://book.51cto.com/art/201205/336658.htm

10.1.2  原子类型

前面我们看到,对于单线程上下文来说,我们可以对整型值简单地使用--和++。但是对于多线程,我们需要使用操作系统/架构原语。这种方式的缺点是即使我们将差异性抽象到一个公共的函数,例如integer_increment中,我们也要时时记住对某个整型值的所有原子操作都必须以该公共函数来完成。然而忘记其中之一是很容易的事情,一旦出现了这种情况,你就可能在应用程序中遭遇一个竞争条件,并且这种东西非常难于诊断。

C++通过允许用户自定义类型和内建类型具有相同的"外观",而支持语法的一致性。那么,为什么不让原子类型从任何方面看起来都跟内建类型一样呢(除了它们的操作是原子的之外)?没有理由不这样做,并且,实际上实现起来也相当简单:1

程序清单10.1

  1. class atomic_integer  
  2. {  
  3. public:  
  4.   atomic_integer(int value)  
  5.     : m_value(value)  
  6.   {}  
  7. // 操作  
  8. public:  
  9.   atomic_integer volatile &operator ++() volatile  
  10.   {  
  11.     atomic_increment(&m_value);  
  12.     return *this;  
  13.   }  
  14.   const atomic_integer volatile operator ++(int) volatile  
  15.   {  
  16.     return atomic_integer(atomic_postincrement(&m_value));  
  17.   }  
  18.   atomic_integer volatile &operator —() volatile;  
  19.   const atomic_integer volatile operator —(int) volatile;  
  20.  
  21.   atomic_integer volatile &operator +=(value_type const &value) volatile  
  22.   {  
  23.     atomic_postadd(&m_value, value);  
  24.     return *this;  
  25.   }  
  26.   atomic_integer volatile &operator -=(value_type const &value) volatile;  
  27.  
  28. private:  
  29.   volatile int m_value;  
  30. };  

这是C++可以使线程编程更容易更简单的领域。然而,关于整型值的自然语义到底有多少应该被该类提供的问题仍然有待推敲。上面的代码展示了在给出原子整型操作的库函数的前提下实现递增/递减以及加减运算是多么的简单。然而,乘法、除法、逻辑操作、移位运算以及另外一些操作则要复杂得多,并且,大多数的原子整型库并不提供这些操作。如果你的代码确实需要它们的话,这就不关我的事了。这种时候,作者往往可以扬长而去,并堂而皇之地说,"这些东西作为一个练习留给读者"。

Boost的原子操作组件使用的正是这种途径:提供atomic_count类型的平台相关的版本,atomic_count仅提供++和--操作(atomic_increment/atomic_decrement)以及隐式转换(atomic_read),因此,如果你决定避开过于复杂的东西,大可心安理得,因为你并不是惟一这么做的人。

原子类型