<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>进程管理 on Codexer</title><link>https://codexer.com/tags/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86/</link><description>Recent content in 进程管理 on Codexer</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Thu, 15 Oct 2026 07:40:00 +0800</lastBuildDate><atom:link href="https://codexer.com/tags/%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86/index.xml" rel="self" type="application/rss+xml"/><item><title>把 codex exec 当工人养：超时、租约、收尾，都得宿主管</title><link>https://codexer.com/posts/2026-10-15-codex-exec-supervised-worker/</link><pubDate>Thu, 15 Oct 2026 07:40:00 +0800</pubDate><guid>https://codexer.com/posts/2026-10-15-codex-exec-supervised-worker/</guid><description>&lt;p&gt;内部发布工具起一个 codex worker，让它更新一个仓库，期望拿回一个跑过测试的补丁。某天宿主进程重启了，你打开日志，看起来什么都正常，就是没有补丁。&lt;/p&gt;
&lt;p&gt;这种时候真正难的问题不在“进程还在不在”。而在：刚才跑的是哪个任务、这些事件属于谁、超时结束的是进程还是只是那一次等待、现在从哪一步接着跑是安全的。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;codex exec&lt;/code&gt; 把 Codex 变成了一个能被别的程序调用的工人。工人被起起来之后，生命周期就归宿主管了。aiopssre 上那篇讲 supervised worker process 的文章把这层责任拆得比较细，下面结合它和我自己踩过的坑说。&lt;/p&gt;
&lt;h2 id="先选层再写监督代码"&gt;先选层，再写监督代码&lt;/h2&gt;
&lt;p&gt;官方文档把 Codex 的集成方式分成三档，先挑对档再动手：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;集成层&lt;/th&gt;
 &lt;th&gt;适合什么&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;codex exec&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;脚本、CI、有边界的后台任务&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Codex SDK&lt;/td&gt;
 &lt;td&gt;应用代码里要程序化地启动、恢复、流式取结果&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;App-server&lt;/td&gt;
 &lt;td&gt;要持久会话、事件流、中断、工具暴露、审批处理的产品&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;一次性的仓库检查当子进程跑就行。产品里有多个并发用户、审批、跨天会话，那就是在要一套协议和会话管理器，用 shell 拼出来可能比直接上 SDK 更费劲。&lt;/p&gt;
&lt;h2 id="jsonl-是过程记录不是结果"&gt;JSONL 是过程记录，不是结果&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;codex exec --json&lt;/code&gt; 吐的是按行分隔的 JSON 事件，命令执行和文件改动都以 item 事件出现。官方评测指南里的例子是：把 trace 存下来，逐行解析，再检查该出现的命令和文件有没有出现。&lt;/p&gt;
&lt;p&gt;这个流能告诉你进度，但一个进度事件离“这件事被接受了”还很远。命令可能起了然后失败，文件可能改了然后构建不过，最后那条 agent 消息听起来像做完了，而该有的产物不在。完成与否要由宿主定义：期望的终止事件、该有的退出码、产物检查，再加一个针对业务的验证器。&lt;/p&gt;
&lt;p&gt;两个细节：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;原始事件流先落盘，再做给界面用的加工。渲染器会合并重复输出、把 reasoning 项藏起来，后面查账的人需要按原始顺序还原，才分得清“终止事件没到”和“界面没显示”。&lt;/li&gt;
&lt;li&gt;敏感信息在源头脱敏，trace 的访问权限要比成品的访问权限更窄。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="一个任务只能有一个进程所有者"&gt;一个任务只能有一个进程所有者&lt;/h2&gt;
&lt;p&gt;子进程起来之前先建 execution ID。这条记录里放：进程 ID、线程 ID（如果有）、工作目录、本次请求的沙箱和审批策略、开始时间、截止时间、期望产物。心跳从观察到的事件里更新。取消和清理归父进程，不归 agent。&lt;/p&gt;
&lt;p&gt;同一个线程不允许两个写者同时恢复。按线程加租约，实现可以简单到数据库里一行原子记录，带所有者和过期时间。子进程活着就续租，子进程退出并且输出流抽干之后才释放。宿主启动时先拿过期租约和真实进程、执行记录对一遍，再决定要不要起新的。&lt;/p&gt;
&lt;p&gt;那条 CAD 的现场报告就是这个问题的实例：Mac 应用从 &lt;code&gt;codex exec --json&lt;/code&gt; 起 worker，把事件映射成聊天步骤，之后用 resume 接着聊。作者说，同一个线程前面那个写者还活着的时候，resume 会失败，所以应用只能等、重试、退出时把子进程收掉。&lt;/p&gt;</description></item></channel></rss>