Workerman 4 通过 pidFile 写入与 posix_kill($pid, 0) 进程存在性校验双重机制防重复启动,不依赖 flock;启动时若 pid 文件存在且对应进程存活则拒绝启动,否则清理并写入新 PID。

Workerman 4 进程 PID 管理的核心不是靠“文件锁”来防重复启动,而是依赖 pidFile 写入 + 进程存在性校验 的双重机制。所谓“文件锁”(如 flock)在 Workerman 启动流程中并不参与控制逻辑,官方也未使用它做互斥;真正起作用的是:启动时检查 pid 文件是否存在且对应进程是否存活,若存活则拒绝启动。
pidFile 是唯一权威的启动状态标识
Workerman 启动时会执行以下判断链:
- 读取
Worker::$pidFile指定的路径(必须为绝对路径,如/var/run/workerman.pid) - 若文件存在,尝试读取其中内容(应为纯数字 PID)
- 用
posix_kill($pid, 0)检查该 PID 进程是否仍在运行(不发送信号,仅探测) - 若进程存在 → 直接报错
Workerman is still running并退出,不覆盖原 pid 文件 - 若进程不存在或文件为空/非法 → 清理旧文件,写入当前主进程 PID,继续启动
为什么不用 flock?
因为 flock 是进程级临时锁,无法跨会话持久化,且 Workerman 主进程启动后即脱离终端,锁句柄会随启动脚本生命周期结束而释放,起不到长期互斥作用。更关键的是:即使加了 flock,只要旧进程已死但 pid 文件残留,flock 也无法感知——而 posix_kill($pid, 0) 能真实反映进程生死,这才是可靠依据。
手动防止重复启动的实操建议
你不需要自己实现文件锁,只需确保三件事:
- 在
start.php开头显式设置:Worker::$pidFile = '/var/run/workerman.pid'; - 确保该路径所在目录可写、文件可创建(例如
sudo chown www-data:www-data /var/run/workerman) - 启动前用命令快速验证:
if [ -f /var/run/workerman.pid ] && kill -0 $(cat /var/run/workerman.pid) 2>/dev/null; then echo "running"; else echo "safe to start"; fi
systemd 下无需担心重复启动
当使用 systemd 托管时(推荐生产环境),Type=simple + Restart=always 已天然规避手动重复执行问题。systemd 会确保同一 service unit 只有一个实例运行,多次 systemctl start workerman 不会触发二次启动,而是返回 “already active”。此时 pidFile 仅用于日志和运维排查,systemd 自身通过 cgroup 和进程树管理生命周期。

















