absl教程(五):Synchronization library

本文详细介绍了Abseil同步库,包括同步概述、互斥体的使用、条件互斥体行为、读写锁、线程注释以及死锁检测。重点讲述了互斥体的实现和功能,如互斥锁的基础、条件临界区、读写锁以及防止死锁的策略。此外,还提到了其他同步操作,如障碍和阻塞计数器,用于管理并发任务中的事件顺序和资源访问。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

同步库包括用于跨不同线程管理任务的抽象和原语。该库包含以下头文件:

  • mutex.h
    提供用于管理资源锁的原语。互斥锁是这个库中最重要的原语,也是大多数并发实用程序的构建块。
  • notification.h
    提供一种简单的机制来通知线程事件。
  • barrier.hblocking_counter.h
    为累积事件提供同步抽象。

Abseilbase库还包括许多与并发相关的头文件:

  • base/thread_annotations.h
    提供用于记录多线程代码的锁定策略的宏,并为滥用此类锁定提供警告和错误。
  • base/call_once.h
    提供一个 Abseil 版本,std::call_once()用于在所有线程中只调用一次可调用对象。

本文档将涵盖上述所有内容。

同步概述

在顺序(即单线程)系统中,我们通常认为事件以特定的总顺序发生:对于任何操作 A 和 B,要么 A 发生在 B 之前,要么 B 发生在 A 之前。在并发系统中,这不再是情况:对于某些操作对,可能无法说哪个更早发生(即事件只是部分排序的),在这种情况下,我们说它们同时发生。请注意,此定义与它们是否“实际上”同时发生无关,而仅与我们是否可以保证它们不会发生有关。

如果在多线

<think>我们正在解决一个关于Abseil库的链接错误问题,具体错误是:`undefined reference to CordzHandle::DiagnosticsHandleIsSafeToInspect`。这个错误通常发生在编译和链接过程中,表明编译器在链接阶段找不到`CordzHandle::DiagnosticsHandleIsSafeToInspect`这个符号的定义。 根据引用[1]和引用[3]的信息,类似的问题往往与编译选项有关,特别是C++标准版本的选择。引用[1]提到,在编译cartographer时,absl库需要以C++17标准进行编译。而引用[4]则提供了修改CMakeLists.txt来设置编译选项的例子,包括设置C++标准为C++11(但根据问题可能需要更高版本)。 因此,我们可以尝试以下步骤来解决这个问题: ### 步骤1: 确保使用正确的C++标准 在编译Abseil库时,需要确保使用C++17或更高版本。这可以通过在CMake配置中设置`CMAKE_CXX_STANDARD`来实现。 例如,在Abseil库的CMakeLists.txt中(或通过CMake命令参数)设置: ```cmake set(CMAKE_CXX_STANDARD 17) ``` 或者,在调用CMake时通过命令行参数指定: ```bash cmake -DCMAKE_CXX_STANDARD=17 ... ``` ### 步骤2: 检查是否使用了相同的ABI 如果项目中使用的是GCC编译器,需要确保所有依赖库(包括Abseil)都使用相同的C++ ABI。在GCC中,这通常意味着需要统一使用新的C++11 ABI(通过定义`_GLIBCXX_USE_CXX11_ABI=1`)或旧的ABI(通过定义`_GLIBCXX_USE_CXX11_ABI=0`)。 可以在编译Abseil库时,通过CMake设置: ```cmake add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=1) # 或者0,根据你的项目需要 ``` ### 步骤3: 确保所有依赖库使用一致的编译选项 如果项目中还有其他库,需要确保它们都使用相同的C++标准和ABI设置。不一致的编译选项可能导致链接错误。 ### 步骤4: 重新编译Abseil库 在修改了编译选项后,需要清除之前的构建并重新编译Abseil库。然后重新构建你的项目。 ### 步骤5: 检查Abseil库的版本 如果上述步骤仍然不能解决问题,可能是Abseil库的版本与你的项目不兼容。尝试使用与你的项目兼容的Abseil版本。你可以查看项目的文档或构建说明以确定兼容的版本。 ### 示例操作(基于引用[3]和[4]的启发) 假设你正在通过`install_abseil.sh`脚本安装Abseil,你可以修改这个脚本以添加必要的编译选项。 在`install_abseil.sh`中,找到CMake配置步骤,并添加设置C++标准的选项: ```bash cmake -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_CXX_STANDARD=17 \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ -S . -B build ``` 然后,再执行构建和安装。 ### 引用说明 根据引用[1],类似的问题通过使用C++17标准编译Abseil库得到了解决[^1]。引用[4]则提供了修改CMakeLists.txt来设置编译选项的示例[^4]。 ### 注意事项 由于编译环境的不同,可能需要根据实际情况调整。如果遇到新的问题,可以检查编译日志以获取更多线索。 §§相关问题§§ 1. 如何检查当前系统中安装的Abseil库的版本? 2. 如何在CMake中统一设置C++标准版本? 3. 如何解决多个库之间ABI不兼容的问题?</think>### 解决 Abseil 库链接错误:`CordzHandle::DiagnosticsHandleIsSafeToInspect`未定义引用 #### 问题分析 此错误通常由以下原因导致: 1. **C++标准不匹配** Abseil 库要求使用 **C++17 或更高标准**编译(尤其是较新版本)。若项目使用较低标准(如 C++11),会导致符号未定义错误[^1][^3]。 2. **编译选项不一致** 主项目与 Abseil 库的编译参数(如 `-fPIC`、优化级别)不一致时,可能引发链接冲突。 3. **ABI 兼容性问题** 不同编译器版本或 ABI 设置(如 `_GLIBCXX_USE_CXX11_ABI`)混用会导致符号解析失败。 --- #### 解决方案 ##### 步骤 1:强制指定 C++17 标准 在编译 Abseil 库时,显式设置 C++17 标准: ```bash # 修改 Abseil 的 CMakeLists.txt 或编译脚本 cd abseil-cpp-build cmake -DCMAKE_CXX_STANDARD=17 \ # 关键:强制 C++17 -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ # 确保生成位置无关代码 -DCMAKE_BUILD_TYPE=Release \ # 建议 Release 模式 .. make -j$(nproc) sudo make install ``` ##### 步骤 2:统一主项目编译选项 在您项目的 `CMakeLists.txt` 中同步设置 C++17: ```cmake # 主项目 CMakeLists.txt cmake_minimum_required(VERSION 3.10) project(your_project) set(CMAKE_CXX_STANDARD 17) # 必须与 Abseil 一致 set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(absl REQUIRED) # 查找 Abseil add_executable(your_target src/main.cpp) target_link_libraries(your_target absl::cord) # 链接所需模块 ``` ##### 步骤 3:检查 ABI 兼容性 如果使用 GCC,确保所有依赖项使用相同的 ABI 设置: ```cmake # 在 Abseil 和主项目中统一添加 add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=1) # 或 =0 取决于系统 ``` ##### 步骤 4:清理并重新编译 ```bash # 彻底清理旧编译文件 rm -rf build/ # 或 catkin_make 的 build 目录 cd your_workspace catkin_make clean # ROS 项目 catkin_make -DCMAKE_CXX_STANDARD=17 # 重新编译 ``` --- #### 验证与调试 1. **检查 Abseil 配置** 运行 `absl-config --cxx-std` 确认安装的 Abseil 使用的 C++ 标准。 2. **查看符号表** 检查 Abseil 库是否包含目标符号: ```bash nm -D /usr/local/lib/libabsl_cord.a | grep DiagnosticsHandleIsSafeToInspect ``` 3. **统一编译环境** 确保所有依赖库(如 Protobuf)均使用相同 C++ 标准编译[^3][^4]。 --- #### 典型错误场景修正示例 若通过 `install_abseil.sh` 脚本安装(如 Cartographer),修改脚本: ```bash # 在 install_abseil.sh 的 cmake 命令中添加: cmake .. -DCMAKE_CXX_STANDARD=17 \ # 关键修复 -DCMAKE_BUILD_TYPE=Release \ # 避免调试符号冲突 -DBUILD_SHARED_LIBS=OFF # 建议静态链接 ``` > **注意**:若仍失败,尝试从源码编译 Abseil 而非系统包管理器安装,以避免版本冲突[^1][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值