便携式比较和交换(原子操作)C / C ++库?

时间:2009-07-21 10:25:22

标签: c++ c multithreading portability lock-free

是否有任何小型库可以将各种处理器的类似CAS的操作包含在宏或函数中,可以跨多个编译器移植?

PS。 atomic.hpp library位于boost :: interprocess :: detail命名空间内。作者拒绝将其作为一个公共的,维护良好的图书馆。

让我们重新打开这个问题,看看是否有其他选择?

9 个答案:

答案 0 :(得分:30)

OPA(Open Portable Atomics)可能非常适合您的需求。 https://trac.mcs.anl.gov/projects/openpa/

它为MIT样式许可下跨多个平台的常见原子操作提供了一致的C API。图书馆很小,当然符合您的尺寸要求。当前的平台列表是:

  • 用于x86,x86_64,ia64,PPC 440和MIPS 5K处理器的GCC内联汇编。一些具有GCC兼容性前端的编译器也支持相同的体系结构,例如icc,PGI和IBM的xlc。
  • GCC原子内在函数,因此支持大多数GCC-4.1 +安装。
  • SUN Solaris原子操作库。
  • Windows NT内在函数(虽然您目前需要在Windows上构建一些额外的工作)。
  • 两个伪平台,pthread基于互斥的仿真,可以移植到其他不受支持的平台(同时牺牲一些性能),以及一个“不安全”的实现,用于有条件地编译为单线程代码的代码。

我从未在C ++程序中使用它,尽管它应该在很少或没有变化的情况下工作。如果遇到麻烦,我很乐意调整它(只需邮寄opa-discuss@lists.mcs.anl.gov)。

答案 1 :(得分:25)

boost interprocess库可能就是你所追求的 - Atomic.hpp包含文件包含各种平台和编译器的比较和交换实现。

答案 2 :(得分:15)

Intel Threading Building Blocks有一个很好的可移植atomic<T>模板,可以满足您的需求。但是,它是否是一个小型图书馆当然可以辩论..

答案 3 :(得分:11)

您可能对Glib's Atomic Operations函数

感兴趣
g_atomic_int_compare_and_exchange()

实现各种体系结构的CAS语义。 实现本身相对容易理解,可以单独使用而不需要太多努力,你可以在glib / trunk / glib / gatomic。{c,h}下的svn.gnome.org/viewvc/找到它。希望这有帮助!

答案 4 :(得分:9)

在Mac OS X和Windows上,无论如何都应该使用内置的CompareAndSwap函数(分别是InterlockedCompareExchange()和OSAtomicCompareAndSwapPtrBarrier())。因此无论这些平台上的编译器如何都可以工作。

在其他Unix上它有点棘手,如果你使用的是GCC 4.1或更高版本,你可以使用它的内置__sync_val_compare_and_swap(),并且很多但并非所有unix编译器都支持合理的gcc扩展,因为源自Linux的大量代码假设他们在场。

因此,如果您希望以适用于OS X和Windows上所有处理器的大多数编译器的方式将它们包装起来,并且使用GCC和其他平台上的其他编译器,您应该执行以下操作:

boolean CompareAndSwapPointer(volatile * void * ptr,
                                  void * new_value,
                                  void * old_value) {
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
  return OSAtomicCompareAndSwapPtr (old_value, new_value, ptr);
#elif defined(_MSC_VER)
  return InterlockedCompareExchange(ptr, new_value, old_value);
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
  return __sync_val_compare_and_swap(ptr, old_value, new_value);
#else
#  error No implementation
#endif
}

未经测试,但我认为应该是正确的。请注意所有OS库如何以不同的顺序获取args; - )

显然,您可以为不同的大小比较做几个版本,并根据需要交换并将它们包装在模板中。这些API主要是基于C的,它将类型信息编码到函数中,这对于那些习惯通过模板参数化类型的人来说非常讨厌。

答案 5 :(得分:6)

Boehm有atomic_ops项目的图书馆。然而,Dunno关于许可证。

答案 6 :(得分:3)

有一个提议的C ++ 0x兼容的Boost原子库:http://www.chaoticmind.net/~hcb/projects/boost.atomic/

  

这个库的目的是   提供原子的实现   基于的提升操作   由C ++ 0x草案指定的接口   标准。它旨在使   过渡到std :: atomic easy,as   以及提供制作代码的方法   使用此C ++ 0x功能可编译   旧系统。

它显然不是Boost的一部分,但您可以在此处查看审核主题:http://lists.boost.org/Archives/boost/2009/12/160195.php

  

Boost.Atomic现在采用我的形式   考虑将其称为发布。它有   支持“真正的”原子变量   于:

     
      
  • gcc / x86,32位(在Linux上测试,FreeBSD)
  •   
  • gcc / x86,64位(在Linux上测试)
  •   
  • gcc / powerpc32(在Linux,Mac OS X上测试)
  •   
  • gcc / powerpc64(未经测试)
  •   
  • 通用Win32(在Win XP上使用Visual Studio Express进行测试)
  •   
     

对于所有其他人,它会退回   优雅地锁定操作。那里   是正确的快速书文档,   包括一个有希望的说明   示例部分。

答案 7 :(得分:2)

作者所说的(在您提供的链接中)是“我认为您可以安全地使用它们,直到某个官方Boost库出现”。推迟接口更改,直到“当原子函数将出现在C ++ 0x中时”。

无论您今天使用什么,无论如何,您可能都希望迁移到新的std::功能。

增强功能通常非常好,看起来它用于实现已发布的Boost库。我也很想过几次使用它。

我会去找它。

答案 8 :(得分:0)

您还可以从http://www.ioremap.net/node/224查看libsync的灵感,这是一个非常新的(可能太新),但它正在Elliptics Network中使用,所以它确实得到了(一些?)测试。

它还为CAS提供了更高级别的原语:RCU(读取复制更新),用于线程之间的无锁同步。

但这取决于你对'便携式'的意思:它支持架构x86和PPC,操作系统Linux,FreeBSD,OpenBSD,Solaris和MacOSX但是......没有Windows。

许可证是GPL,你可以讨厌或爱。