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

30 c c++ multithreading portability lock-free

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

PS.atomic.hpp库是升压::进程间::详细的命名空间中.作者拒绝将其作为一个公共的,维护良好的图书馆.

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

Dav*_*ell 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).


Ste*_*ham 25

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

  • 但Boost的atomic.hpp只有32位整数的原子.一个好的原子库也会有64位的int原子和指针原子. (2认同)

Kri*_*ian 15

英特尔线程构建模块有一个很好的可移植atomic<T>模板,可以满足您的需求.但是,它是否是一个小型图书馆当然可以辩论..

  • 我将TBB纳入了我的项目.谢谢. (2认同)

llo*_*ngi 11

您可能对Glib的Atomic Operations功能感兴趣,

g_atomic_int_compare_and_exchange()
Run Code Online (Sandbox Code Playgroud)

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


Lou*_*arg 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
}
Run Code Online (Sandbox Code Playgroud)

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

显然,你可以为不同大小的比较做一些版本比较和交换,如果你愿意,可以将它们包装在模板中.API主要是基于C的,并且将类型信息编码到函数中,使得它对于用于通过模板参数化类型的人来说是一种讨厌的.


Dir*_*irk 6

Boehm 有atomic_ops项目的库.然而,Dunno关于许可证.

  • "我们的目的是在自由软件和专有软件中使用libatomic_ops变得容易.因此,我们期望链接到客户端应用程序的大多数代码都被MIT样式的许可证覆盖.GNU涵盖了一些库例程通用公共许可证.这些被放入一个单独的库libatomic_ops_gpl.a." (4认同)