c/c++中exit()和_exit()的区别

在C/C++中,exit() 和 _exit() 都是用来终止程序执行的函数,但是它们之间有一些关键的区别。
exit():

        exit() 函数是在 <stdlib.h> 中定义的,它是C标准库的一部分,提供了更高级别的终止行为。当你调用 exit() 时,它会触发一系列的操作:

    1.调用所有注册的终止处理函数(cleanup functions),这些函数可以通过 atexit() 注册。
    2.尝试刷新C标准I/O流(即 stdout 和 stderr)的缓冲区。
    3.终止程序,传递一个状态码给操作系统,该状态码可以被父进程或其他工具捕获以了解程序的退出原因。

exit() 是一个比较“优雅”的退出方法,因为它确保了所有的资源被适当地清理,使得程序能够在正常情况下结束。


_exit()

        _exit() 是一个系统调用,它直接位于操作系统级别,并且定义在 <unistd.h> 中。它是一个低级别的函数,不执行任何清理操作。当你调用 _exit() 时:

    1.它不会调用任何注册的终止处理函数。
    2.不会刷新C标准I/O流的缓冲区。
    3.直接终止程序并将一个状态码传递给操作系统。

_exit() 常用于子进程中,当父进程不希望子进程执行任何清理操作时使用。这是因为子进程的资源通常会在父进程继续运行时由操作系统自动回收。


何时使用哪个?

    如果你需要保证程序在退出前释放所有资源,并且希望执行一些清理工作(比如关闭文件、释放内存等),那么你应该使用 exit()。
    如果你在一个子进程中,并且不关心资源的释放(例如,子进程的任务已经完成,不需要做任何额外的工作),那么可以使用 _exit()。

这个编译错误信息: ``` ERROR: /apollo/modules/perception/env/src/BUILD:96:11: C++ compilation of rule '//modules/perception/env/src:local_map_master' failed (Exit 1) ``` 表明在使用 Bazel 构建 Apollo 项目时,`//modules/perception/env/src:local_map_master` 这个目标的 C++ 编译失败了。虽然你只贴出了错误头,没有给出具体的编译器输出(如 `error: no matching function for call...` 等),但从路径工具链来看,这通常与 **CUDA、C++ 标准版本不兼容、缺失依赖或头文件路径问题**有关。 --- ### 🔍 常见原因分析 1. **CUDA 工具链配置问题** - 错误中提到了:`external/local_config_cuda/crosstool/clang/bin/crosstool_wrapper_driver_is_not_gcc` - 这说明正在使用 CUDA 的交叉编译包装器来编译 C++ 代码。 - 如果你的系统 CUDA 版本与 Apollo 要求的不匹配(比如 Apollo 需要 CUDA 10.2,而你装的是 11.8),就会导致编译失败。 2. **C++ 标准不一致(如 C++11 vs C++14)** - Apollo 某些模块要求特定的 C++ 标准(通常是 C++14)。 - 若 BUILD 文件未正确设置 `cxx_standard`,或 NVCC 不支持该标准,会报错。 3. **头文件缺失或路径错误** - `local_map_master.cc` 可能包含了一些未找到的头文件(例如来自 PCL、Boost 或自定义模块)。 4. **GPU 架构不匹配** - 编译时若指定的 GPU compute capability(如 sm_75)与实际硬件不符,也会失败。 5. **内存不足或并发编译崩溃** - 在 Docker 容器中构建时,资源受限可能导致 `crosstool_wrapper_driver_is_not_gcc` 崩溃退出。 --- ### ✅ 解决方案步骤 #### ✅ 步骤 1:查看完整错误日志 你需要看到 **完整的编译错误输出**,而不仅仅是 Bazel 报错头。 运行以下命令获取详细错误: ```bash bazel build //modules/perception/env/src:local_map_master --verbose_failures ``` 或者开启调试模式: ```bash bazel build //modules/perception/env/src:local_map_master --subcommands=pretty_print ``` > 👉 这将显示完整的 g++/nvcc 命令行及其错误输出,定位具体哪一行代码出错。 --- #### ✅ 步骤 2:检查 CUDA GCC 兼容性 Apollo 对 CUDA GCC 有严格要求。例如 Apollo 6.0 推荐: - Ubuntu 18.04 - GCC 7.5.0 - CUDA 10.2 - cuDNN 7.6.5 你可以检查当前环境: ```bash nvcc --version gcc --version ``` 如果你使用的是较新的显卡驱动/CUDA(如 12.x),可能需要降级或使用官方 Apollo Docker 镜像。 --- #### ✅ 步骤 3:确认 BUILD 文件配置 打开 `/apollo/modules/perception/env/src/BUILD` 第 96 行附近的规则: ```python cc_binary( name = "local_map_master", srcs = ["master.cc"], deps = [ "//modules/perception/lib:point_cloud", "//some/other/deps", ], ) ``` 确保: - 所有依赖项存在且可构建; - 若涉及 `.cu` 文件,应使用 `cuda_library` 或启用 `--config=cuda`; - 包含正确的 C++ 标准: ```python copts = ["-std=c++14"], ``` 可以在全局 `.bazelrc` 中加入: ```ini build --cxxopt=-std=c++14 ``` --- #### ✅ 步骤 4:尝试清理并重新构建 ```bash bazel clean --expunge rm -rf /tmp/bazel_* # 清理临时文件 bazel build //modules/perception/env/src:local_map_master --verbose_failures ``` --- #### ✅ 步骤 5:使用 Apollo 官方 Docker(推荐) 最稳妥的方式是进入 Apollo 提供的开发容器: ```bash bash docker/scripts/dev_start.sh bash docker/scripts/dev_into.sh ``` 然后在容器内编译: ```bash cd /apollo git checkout r6.0.0 # 或对应分支 bazel build //modules/perception/env/src:local_map_master ``` 这样可以避免本地环境差异带来的问题。 --- ### 🛠 示例修复:添加 C++14 支持 假设问题是由于缺少 C++ 标准导致,在 `BUILD` 文件中修改: ```python cc_binary( name = "local_map_master", srcs = ["master.cc"], copts = [ "-std=c++14", "-Wall", "-Wextra", ], deps = [ "//modules/perception/lib:point_cloud", "//cyber", ], ) ``` 并在 `.bazelrc` 添加: ```ini build --cxxopt=-std=c++14 ``` --- ### ❓ 如何判断是否是 CUDA 编译问题? 如果源码中有 `.cu` 文件或混合编译 `.cc` 与 CUDA 头文件(如 `<cuda_runtime.h>`),则必须使用 `cuda_cc_library` 而非普通 `cc_library`。 否则会出现“undefined reference to cuda”或“invalid device function”。 --- ### ✅ 总结解决流程 | 步骤 | 操作 | |------|------| | 1 | 使用 `--verbose_failures` 查看完整错误 | | 2 | 检查 CUDA/GCC 是否符合 Apollo 要求 | | 3 | 修改 BUILD 文件添加 `-std=c++14` | | 4 | 清理缓存后重试 | | 5 | 使用官方 Docker 开发环境 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值