Oracle® Developer Studio 12.5:C++ 用户指南

退出打印视图

更新时间: 2016 年 7 月
 
 

11.2.3 捆绑的原子库

原子是 C11 和 C++11 标准中新增的一种语言功能,它需要来自操作系统的运行时支持。有关使用原子功能的更多信息,请参见 atomic_fence(3A)atomic_flag(3A)stdatomic.h(3A) 手册页。

由于还没有用于此运行时支持的标准接口,因此,gcc 原子库和 Oracle Developer Studio 原子库之间稍有差异。

GCC 通过名为 libatomic.so(在 Oracle Solaris 11.3 和 Oracle Linux 7.x 上,它包括在 /usr/lib 中)的运行时库来支持原子。

Oracle Developer Studio 12.5 编译器通过名为 libstatomic.so 的新运行时库来支持原子。此库与 Oracle Developer Studio 发行版捆绑在一起,且未包括在 Oracle Solaris 或 Oracle Linux 中。这是可以将 GCC 和 Oracle Developer Studio 库合并和并入 Oracle Solaris 之前以及 Oracle Linux 捆绑的库符合标准接口之前的临时解决方案。

libstatomic.so 库已经过测试,与 libstatomic.so 的 GCC 4.8、4.9 和 5.1 发行版兼容,与 GCC 原子库 libatomic 的兼容性中讨论了一些例外情况。

使用新的编译器选项 –xatomic,可以指定在链接程序和库时是使用 GCC libatomic 库还是使用 Oracle Developer Studio libstatomic 库。

11.2.3.1 选择原子库

可以选择使用 Oracle Developer Studio 原子库 (libstatomic.so) 或 GCC 原子库 (libatomic.so),但是在链接在一起的可执行文件和库之间务必将此保持一致。在正在运行的进程中,应当仅使用一个原子库。


注 -  如果不需要与 gcc 生成的使用原子的库兼容,则应该将 libstatomic.so 与 Oracle Developer Studio 编译器一起使用。

要控制在链接时使用的库,请使用 –xatomic 选项。要链接到 Oracle Developer Studio 的库 libstatomic,请使用 –xatomic=studio;要链接到 GCC 的库 libatomic,请使用 –xatomic=gcc。要阻止与某个库进行链接,请使用 –xatomic=none

为了帮助移植使用 GCC 编译器的现有 Makefile 或源代码,如果向编译器传递了 –latomic,该选项将转换为 –xatomic=studio

对于 C++ 程序,当需要时,缺省情况下会链接原子支持库。


注 -  –xatomic=none 选项可确保应用程序不会将 Oracle Developer Studio libstatomic 安装目录作为运行路径。为了生成使用 –xatomic=none 调用库函数的应用程序,在生成时应该显式链接 libstatomic.so

部署使用 libstatomic.so 的应用程序

作为 Oracle Developer Studio 产品的一部分,捆绑的原子库 libstatomic.so 完全受支持。您可以部署使用该库的应用程序,但是除非应用程序在已安装了 Oracle Developer Studio 的系统上运行,否则需要包括该库。

  1. 确定从您的可执行文件到 listatomic.so 的运行时路径。

    例如:

    ./lib
  2. 确定 libstatomic.so 的生成时路径。

    例如:

    build-path/import/libstatomic.so
  3. –xatomic=none 添加到链接步骤。
  4. 添加新的链接时选项。

    例如:

    –R runtime-path build-path-to-atomics/libstatomic.so.1
  5. 将 libstatomic 库复制到您自己的产品安装树中。
示例 3  myprog 可执行文件包含 libstatomic.so

以下示例在未安装 Oracle Developer Studio 的 64 位 SPARC 平台上部署应用程序。

在生成计算机上生成应用程序之前,请确定要将 libstatomic 放置到的相对于可执行文件的位置。例如,如果应用程序位于 app_root,而 libstatomic 库在 app_root/lib 中,则该库的相对目录是 ./lib

bash-4.1$ ls app_root/
lib     myprog
bash-4.1$ ls app_root/lib/
libstatomic.so    libstatomic.so.1

在生成计算机上,确定 libstatomic.so 的位置。例如,如果 Oracle Developer Studio 安装在 install-dir/ 中,则 libstatomic.so 位于 install-dir/lib/compilers/atomic/sparcv9/libstatomic.so 中。

使用以下命令编译程序:

$ install-dir/bin/CC -m64 [compiler-options] -xatomic=none myprog.cc -o myprog -R'$ORIGIN'/lib install-dir/lib/compilers/atomic/sparcv9/libstatomic.so

在部署计算机上,创建软件包目录。

然后将 64 位 libstatomic.so 库复制到 app_root/lib

$ cp install-dir/lib/compilers/atomic/sparcv9/libstatomic.so app_root/lib

将为 myprog 生成的可执行文件复制到 app_root 目录。这样,在执行 myprog 时,运行时链接程序就可以在 ./lib 下找到 libstatomic.so

$ cp myprog.out app_root

11.2.3.2 与 GCC 原子库 libatomic 的兼容性

如果您的应用程序或库使用原子,且它需要与使用 GCC 版本的 libatomic 的可执行文件和库互操作,则必须将您的 Oracle Developer Studio 程序与 GCC 版本的 libatomic 链接在一起。请务必确保程序中只有一个版本的原子运行时库。

要将 Oracle Developer Studio C 和 C++ 程序与 GCC 版本的 libatomic 链接在一起,请使用编译器选项 –xatomic=gcc

如果您在较旧的系统上(/usr/lib 中没有 GCC 版本的 libatomic)链接和运行,则不必担心不兼容的原子支持。在这种情况下,可以将 libstatomic 与该系统上的 GCC 二进制文件组合使用,因为没有其他原子库在使用中。

Oracle Developer Studio 编译器最适合 libstatomic 库,但是与 GCC 的 libatomic 版本 1.1 兼容,且具有下面列出的已知问题:

  • GCC 4.8 包括 libatomic 1.0.0。- 如果在 C 11 程序中避免使用浮点原子,则此版本的 libatomic 支持 C11 和 C++11 原子。在更高版本的发行版推出之前,GCC 4.8 编译器本身不支持 C11。

  • GCC 4.9 和 5.1 包括 libatomic 1.1。- 此版本包括 C11 的浮点原子,具有这些版本的 GCC 编译器支持 C11 原子关键字。


    注 -  C11 程序可能会采用原子函数的地址,这仅对非通用函数是合法的。与 libatomic 1.0.0 或 libatomic 1.1 一起使用时,这将无法正常工作,因为库假定所有的原子函数始终由编译器内联且不需要库中的代码。可以在 atomic 手册页中查看这些函数的列表。如果需要获取这些函数的函数指针,则应该使用 libstatomic

Oracle Linux 7.x 和 Oracle Solaris 11.3 包括带有 libatomic 1.0.0 的 GCC 4.8。

11.2.3.3 实现说明

如果多个组件(例如可执行文件或共享库)需要原子运行时,则应该将每个组件与相应的 –xatomic 选项动态链接以创建正确的动态依赖关系。不应生成在链接库时需要提供原子选项的共享库。

由于以下原因,建议不要在同一进程中同时使用这两个运行时库:

  • 一些原子类型需要调用运行时支持库才能执行同步。两个运行时系统具有不同的内部数据结构,因此两个库无法同步同一对象。

  • Oracle Developer Studio 库 libstatomic 为函数使用与 libatomic 相同的全局符号名称。如果在同一进程中使用两个库,则可执行文件或库可能会调用非预期库中的函数。

尝试同时使用两个运行时库的程序可能最初看起来可以工作,但是很可能会失败且无法为其提供支持。


注 -  使用 –latomic 进行链接不会导致与 /usr/lib/libatomic.so.1 链接在一起。该库是 GCC 实现,其目的是与 GCC 一起使用,直到在 Oracle Solaris 和 Oracle Linux 中发布兼容库为止。

由于许多原子操作是内联的,因此应用程序也许能够使用原子功能,而不依赖于原子运行时库。行为是特定于实现的,因此如果升级编译器,则结果可能会更改。如果您的应用程序仅使用标量原子类型(flagscharintlongpointers),且在 x86 平台上生成,则生成的库可能不需要 libstatomic。可以尝试使用 –xatomic=none 选项编译这样的应用程序或库,并检查它是否正确地链接和运行。