Process-on使用记录

由于博客内容为空,暂无法提供包含关键信息的摘要。

 

# 题目重述 你运行了一个带日志记录的多进程调试脚本,输出如下: ``` 2025-11-24 11:16:20,134 - MainProcess - Main process started 2025-11-24 11:16:20,145 - MainProcess - Started Worker-0, PID=37908 2025-11-24 11:16:20,158 - MainProcess - Started Worker-1, PID=29792 2025-11-24 11:16:20,240 - MainProcess - Worker-Worker-0 exited with code 1 2025-11-24 11:16:20,246 - MainProcess - Worker-Worker-1 exited with code 1 2025-11-24 11:16:20,246 - MainProcess - Final progress: 0 ``` 你想知道:这说明了什么? --- ## 详解 这个日志结果非常清晰地揭示了问题的本质。我们逐行分析: --- ### ✅ 行 1:`Main process started` - 主进程正常启动; - 日志系统初始化成功; - ✅ 环境基本可用。 --- ### ✅ 行 2–3:`Started Worker-0, PID=...` - 成功创建两个 `Process` 对象; - 调用了 `p.start()`; - 操作系统已分配新 PID(如 37908); - ✅ **进程创建层面是成功的**。 --- ### ❌ 行 4–5:`Worker-Worker-0 exited with code 1` > 实际应为 `Worker-0`,但显示 `Worker-Worker-0` → 可能命名拼接错误,不影响判断。 关键点: - 所有子进程在 **极短时间内退出(<100ms)**; - `exitcode=1` 表示异常终止; - `Final progress: 0` → 共享变量未被任何子进程修改。 👉 **结论:子进程根本没有执行 `worker` 函数!** --- ## 🔍 根本原因:函数无法反序列化(UnpicklingError) 这是 **Jupyter Notebook + Windows/macOS + multiprocessing.spawn** 的经典致命问题。 ### 🧠 原理详解: 当调用 `p.start()` 时,Python 使用 `spawn` 模式启动子进程: 1. 子进程重新运行 Python 解释器; 2. 尝试从主模块中导入目标函数 `worker`; 3. 但在 Jupyter 中,代码位于一个“虚拟模块”中(不是 `.py` 文件); 4. 导致: ``` AttributeError: Can't get attribute 'worker' on <module '__main__'> ``` 5. 此异常发生在底层 `pickle` 层,不会打印到 notebook; 6. 子进程直接崩溃退出,返回 `exitcode=1`; 7. 用户代码(如日志、计数器)完全未执行。 --- ### 📊 证据链总结 | 现象 | 推论 | |------|------| | 子进程 PID 被分配 | 进程已创建 | | 退出时间极短(~100ms) | 未进入业务逻辑 | | `exitcode=1` | 非正常退出 | | `progress.value == 0` | 无子进程执行过 `with lock:` | | 无子进程日志文件生成 | `init_logger` 或 `logging` 未执行 | | 综合判断 | ❌ 子进程未能成功反序列化 `worker` 函数 | --- ### ✅ 如何验证? 你可以添加一行“最基础”的测试,在函数外写一个全局标志: ```python # 在文件顶部加 import atexit import os def _log_subprocess_start(): if os.environ.get('IN_SUBPROCESS') == '1': with open("subprocess_reached.txt", "w") as f: f.write("Subprocess started") atexit.register(_log_subprocess_start) ``` 然后修改 `worker` 第一行: ```python def worker(...): os.environ['IN_SUBPROCESS'] = '1' # 触发记录 ... ``` 如果运行后 **没有生成 `subprocess_reached.txt`** → 说明连 `worker` 函数都没进入 → 确认为反序列化失败。 --- ### ✅ 最终解决方案(无需新建文件) 虽然你不能创建 `.py` 文件,但可以尝试以下方法提高成功率: #### ✅ 方法一:强制使用 `__name__ == "__main__"` 并设置 spawn ```python if __name__ == "__main__": import multiprocessing as mp try: mp.set_start_method('spawn', force=True) except RuntimeError: pass # 你的所有 Process 启动逻辑放在这里 ``` #### ✅ 方法二:缩小规模先验证 ```python ALL_LABELS = ['一'] # 只测试一个汉字 count = 1 num_processes = 1 ``` #### ✅ 方法三:改用单进程临时绕过 ```python # 替代多进程:用于验证逻辑是否正确 for chunk in label_chunks: worker(0, chunk, FONT_PATH, shared_counter, counter_lock, LOG_DIR) ``` 如果这时能生成日志和进度 → 说明业务逻辑没问题,只是多进程环境受限。 --- ### 知识点(列出解答该问题需要的知识点) - **Python 多进程反序列化机制**:子进程通过 `pickle` 查找函数,若不在可导入模块中则失败。 - **Jupyter 中命名空间隔离**:notebook 单元格中的函数不属于任何 `.py` 模块,导致 `spawn` 模式无法加载。 - **Exit Code 1 的含义**:表示子进程因未捕获异常或导入失败而提前终止。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值