3.4 进程管理_进程终结

本文介绍了进程终结时如何释放资源并通知父进程的过程。详细解释了进程析构发生在调用exit()之后,以及如何通过wait()函数获取子进程退出信息。

    当一个进程终结时,内核必须释放它所占有的资源并把这一不幸告知其父进程。

    一般说来,进程的析构发生在它调用exit()之后,既可能显示地调用这个系统调用,也可能隐式地从某个程序的主函数返回(其实C语言编译器会在main()函数的返回点后面放置调用exit()的代码)。

 

3.4.1 删除进程描述符

    在调用了do_exit()之后,尽管线程已经僵死不能再运行了,但是系统还保留了它的进程描述符。这样做可以让系统有办法在子进程终结后仍能获得它的信息。因此,进程终结时所需的清理工作和进程描述符的删除被分开执行。在父进程获得已终结的子进程的信息后,或者通知内核它并不关注那些信息后,子进程的task_struct结构才被释放。

    wait()的标准动作时挂起调用它的进程,直到其中的一个子进程退出,此时函数会返回该子进程的PID.   

<think>我们遇到了一个RKNN构建错误,提示缺少GLIBCXX_3.4.29,但用户已经通过`strings`命令确认系统中存在该符号版本。这表明问题可能不在于缺失库文件,而在于运行时加载了错误版本的库。 ###问题原因分析1. **多版本库冲突**:系统可能存在多个`libstdc++.so.6`版本,而RKNN运行时加载了旧版本(不包含GLIBCXX_3.4.29)[^1]。 2. **环境变量覆盖**:`LD_LIBRARY_PATH`可能优先指向旧版库路径,导致新版库未被加载。 3. **RPATH设置**:RKNN的共享库(如`libcpputils.so`)可能硬编码了库搜索路径,覆盖系统默认路径。 4. **动态链接缓存未更新**:`ldconfig`缓存未刷新,导致旧版库仍被使用。###解决方案####步骤1:确认运行时加载的库版本```bash#检查RKNN进程实际加载的libstdc++.so.6路径ldd/usr/local/python3.10/lib/python3.10/site-packages/rknn/api/lib/linux-x86_64/cp310/libcpputils.so |grep libstdc++#输出示例: #libstdc++.so.6=> /old/path/libstdc++.so.6(0x00007f...)```若输出路径不是新版库(如指向`/usr/lib/x86_64-linux-gnu/`下的旧版),则需干预加载顺序。 ####步骤2:强制指定库路径(三种方法)#####方法1:设置`LD_LIBRARY_PATH`(临时) ```bash#定位包含GLIBCXX_3.4.29的libstdc++.so.6目录(如GCC11的路径)export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/11:$LD_LIBRARY_PATH#然后运行RKNN构建命令pythonyour_script.py```#####方法2:修改RPATH(永久)```bash#使用patchelf修改RKNN库的RPATH(需先安装patchelf)sudo aptinstall patchelf#Ubuntu/Debian#修改libcpputils.so的库搜索路径patchelf --set-rpath &#39;$ORIGIN:/usr/lib/gcc/x86_64-linux-gnu/11&#39; \/usr/local/python3.10/lib/python3.10/site-packages/rknn/api/lib/linux-x86_64/cp310/libcpputils.so```#####方法3:更新系统默认库链接```bash#确保新版库在ldconfig缓存中echo"/usr/lib/gcc/x86_64-linux-gnu/11"| sudotee /etc/ld.so.conf.d/gcc11.confsudoldconfig#检查是否已更新ldconfig -p |grep libstdc++.so.6```####步骤3:验证修复```bash#检查RKNN库的依赖解析ldd /usr/local/python3.10/lib/python3.10/site-packages/rknn/api/lib/linux-x86_64/cp310/libcpputils.so |grep libstdc++#应输出新版路径:=>/usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so.6```###根本原因与预防-**动态链接优先级规则**:Linux加载共享库时按以下顺序[^2]:1.执行文件的RPATH2. `LD_LIBRARY_PATH`3.`/etc/ld.so.cache`4.默认路径(`/usr/lib`等)- **预防措施**:-使用容器(如Docker)隔离RKNN环境-在较新发行版(如Ubuntu22.04+)中部署###示例:在Ubuntu18.04上的完整修复流程```bash#安装GCC11sudoadd-apt-repository ppa:ubuntu-toolchain-r/testsudoapt updatesudoapt installgcc-11g++-11#确认新版库包含GLIBCXX_3.4.29strings/usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so.6| grepGLIBCXX_3.4.29#更新动态链接sudo ln-sf/usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so.6/usr/lib/x86_64-linux-gnu/sudo ldconfig#设置环境变量(可选) exportLD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/11:$LD_LIBRARY_PATH```> **注意**:如果系统中有其他应用依赖旧版库,建议使用`LD_LIBRARY_PATH`局部覆盖而非替换系统库。 通过上述调整,RKNN应能正确加载新版C++标准库,解决构建错误。###相关问题1.如何在不影响系统其他应用的情况下为特定程序升级`libstdc++`?2.RKNN模型部署时出现`undefinedsymbol:_ZSt24__throw_out_of_range_fmt...`该如何解决?3.使用Docker容器运行RKNN的最佳实践是什么? 4.如何检查Linux动态链接库的加载顺序?</think>### RKNN构建错误:`GLIBCXX_3.4.29`存在但仍报错的原因与解决方案 #### 问题本质分析 当`strings`命令显示系统中存在`GLIBCXX_3.4.29`符号,但RKNN仍报告缺失时,核心问题在于**动态链接器未正确加载新版库**。根本原因如下: 1. **多版本库冲突** 系统存在多个`libstdc++.so.6`副本(如GCC 11GCC 9共存),但RKNN通过`LD_LIBRARY_PATH`或`ldconfig`缓存加载了旧版本。 2. **路径优先级问题** `/usr/lib/x86_64-linux-gnu/`路径优先级高于`/usr/lib/gcc/`目录,导致旧版库被优先加载。 3. **硬编码RPATH干扰** RKNN的共享库(如`libcpputils.so`)可能包含硬编码的库搜索路径,覆盖系统默认路径[^1]。 --- ### 诊断与解决方案 #### 步骤1:确认运行时加载的库版本 ```bash # 检查RKNN实际加载的库路径 ldd /usr/local/python3.10/lib/python3.10/site-packages/rknn/api/lib/linux-x86_64/cp310/libcpputils.so | grep libstdc++ # 示例输出(问题场景): # libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (旧版) ``` #### 步骤2:强制指定新版库路径(三种方法) ##### 方法1:设置`LD_LIBRARY_PATH`(推荐) ```bash # 定位包含GLIBCXX_3.4.29的库目录(如GCC 11的路径) export LD_LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/11:$LD_LIBRARY_PATH # 验证环境变量 echo $LD_LIBRARY_PATH ``` ##### 方法2:更新`ldconfig`缓存 ```bash # 添加新版库路径到配置文件 echo "/usr/lib/gcc/x86_64-linux-gnu/11" | sudo tee /etc/ld.so.conf.d/gcc11.conf # 更新动态链接器缓存 sudo ldconfig # 检查是否生效 ldconfig -p | grep libstdc++.so.6 ``` ##### 方法3:修改RPATH(高级) ```bash # 安装patchelf工具 sudo apt install patchelf # 修改RKNN库的RPATH指向新版 patchelf --set-rpath &#39;/usr/lib/gcc/x86_64-linux-gnu/11:$ORIGIN&#39; \ /usr/local/python3.10/lib/python3.10/site-packages/rknn/api/lib/linux-x86_64/cp310/libcpputils.so ``` #### 步骤3:验证修复效果 ```bash # 检查实际加载的库 ldd /path/to/libcpputils.so | grep libstdc++ # 应输出新版路径:=> /usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so.6 # 测试RKNN构建 python -c "from rknn.api import RKNN; print(RKNN().build())" ``` --- ### 根本原因详解 - **动态链接器工作原理** Linux加载共享库时按以下优先级[^2]: 1.执行文件的RPATH 2. `LD_LIBRARY_PATH`环境变量 3. `/etc/ld.so.cache`缓存 4. 默认系统路径`/usr/lib/` 当RKNN的库包含硬编码RPATH时,会跳过系统路径。 - **版本冲突示例** 假设系统中有: - GCC 9:`/usr/lib/gcc/x86_64-linux-gnu/9/libstdc++.so.6`(无GLIBCXX_3.4.29) - GCC 11:`/usr/lib/gcc/x86_64-linux-gnu/11/libstdc++.so.6`(含目标符号) 若`ldconfig`缓存指向GCC9路径,则报错发生。 --- ### 永久性解决方案 ```mermaid graph TD A[问题现象] --> B{检查库版本} B -->|strings 确认存在| C[诊断加载路径] C --> D[设置LD_LIBRARY_PATH] C --> E[更新ldconfig] C --> F[修改RPATH] D --> G[验证修复] E --> G F --> G G -->|成功| H[正常构建RKNN] G -->|失败| I[使用Docker容器] ``` #### 推荐:容器化方案(彻底隔离) ```dockerfile # Dockerfile示例 FROM ubuntu:22.04 RUN apt update && apt install -y python3-pip RUN pip install rknn-toolkit2 # 验证glibcxx版本 RUN strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX_3.4.29 ``` 构建命令: ```bash docker build -t rknn_env . docker run -it --rm rknn_env python your_script.py ``` > **关键提示**:Ubuntu 22.04默认包含GCC 12(提供GLIBCXX_3.4.30),完全兼容此需求[^3]。 --- ### 相关问题 1. 如何在不影响其他应用的情况下为RKNN单独升级`libstdc++`? 2. Docker容器中部署RKNN模型的最佳实践是什么? 3. 如何检测Linux动态库的加载优先级? 4. RKNN模型转换时出现`undefined symbol`错误如何解决? 5. 多版本GCC共存时如何管理库依赖?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值