Linux pidfd_send_signal怎样向指定进程安全发送信号
Linux pidfd_send_signal 通过进程文件描述符发送信号。正确用法是先在目标身份可信时取得 pidfd,并在该进程实例的管理周期内持有它;需要停止时向同一个 pidfd 发送 SIGTERM。这样即使原进程退出、数字 PID 被复用,旧句柄也不会转而指向后来占用该 PID 的进程。
这里的“安全”指减少发错进程的竞争条件,并不代表绕过信号权限,也不代表 SIGTERM 返回成功就一定已经退出。示例只讨论管理器负责的普通进程,不扩展到线程定向或进程组广播。
Linux man-pages 官方项目地址:https://www.kernel.org/doc/man-pages/
停止请求必须绑定进程实例
假设任务管理器保存了某次工作进程的 PID。几分钟后,用户点击停止;如果工作进程早已退出,保存的数字就可能已经属于另一进程。此时直接调用 kill(pid, SIGTERM),内核按调用当时的 PID 找目标,不知道应用原本想停止哪个任务。
先调用 kill(pid, 0) 再发信号,也不能把两次调用合成一次原子身份确认。中间仍有进程退出与 PID 复用的机会。sig 为 0 仅检查相应目标的存在性与权限,本身不发送信号。
pidfd 改变的是管理器保存的对象:任务记录里不只存数字,还保存绑定特定实例的句柄。它像文件描述符一样由管理器持有,但引用的是目标进程身份。业务任务编号仍要单独保留,用来关联用户请求和日志。
不过,若从一个过期 PID 文件中取出数字,等到发送前才调用 pidfd_open,获取句柄之前仍可能已经发生复用。成功打开只能说明绑定到了那一刻的目标,无法证明它就是几分钟前的旧任务。因此句柄要尽早取得,不能拿它弥补不可信的进程来源。

拿到句柄后把它放进任务记录
对于已有且身份可信的进程,可调用 pidfd_open(pid, 0) 取得 pidfd。对于管理器自己创建的子进程,可以研究在创建时使用 CLONE_PIDFD 直接取得句柄,减少从“创建返回PID”到“另行打开句柄”的身份管理负担。
如果采用 fork 后再 pidfd_open 的组合,必须保证子进程不会在这期间被提前回收。man-pages 特别列出了 SIGCHLD 被忽略、SA_NOCLDWAIT 或其他线程提前执行 wait 等会破坏相应保证的情况。多线程管理器应统一创建、回收与任务登记的职责,不能仅凭“这是我的子进程”就忽略这些条件。
任务记录可以包含 task_id、pid_for_log、pidfd、stop_requested 和 exit_observed。其中 pidfd 是当前进程里的文件描述符编号;不能把这个整数持久化到数据库后,期待管理器重启仍可直接使用。管理器恢复需要重新建立受控的进程关联方案。
用同一pidfd发送SIGTERM
下面是原创的管理器集成片段。它不解析任意用户输入,也不在函数内部重新查找 PID。调用方负责在可信绑定阶段取得句柄;发送阶段只接受已经持有的 pidfd。示例使用 syscall 形式,要求编译头文件提供对应 SYS 常量。
#define _GNU_SOURCE #include#include #include #include #include /* 仅在目标身份已有可靠来源时调用;成功返回由调用方负责关闭的句柄。 */ static int bind_process(pid_t trusted_pid) { if (trusted_pid
这两个辅助函数把系统调用的 -1 + errno 转成了负错误码;这种约定是示例自己的接口设计,不要与原始系统调用返回方式混淆。绑定成功后把 fd 放进任务记录,后续停止请求复用它,而不是重新把 pid_for_log 转回新句柄。
函数返回 0 时可记录“停止信号已请求”,不要直接写“任务已停止”。目标可以捕获、阻塞或忽略 SIGTERM;应用还可能需要完成清理。若设置停止宽限期,计时与后续动作也应关联同一任务记录和同一持有句柄。
把发送结果和退出结果分开记录
管理器需要独立的退出观察。pidfd 可以接入 poll 或 epoll;事件表示目标的相关退出状态已可观察,不能像管道一样调用 read 读取一段进程输出。进程日志仍应来自单独的日志文件或管道。
对于本管理器的子进程,可使用 waitid(P_PIDFD, ...) 取得等待信息并执行相应回收。普通非子进程并不会因为你持有 pidfd 就自动变成可 wait 的子进程;此时不能把 ECHILD 一概当作 pidfd 无效。
任务层应分别记录信号请求结果、退出事件和最终业务结果。比如信号已发送但仍在等待,或尚未请求停止就已经自然退出,这些都应有可表达的状态。子进程退出码、终止信号和业务输出是否完整,也不能由发送接口的返回值代替。

异常处理和句柄关闭一起设计
| 情况 | 应当理解为什么 | 任务层处理 |
|---|---|---|
| 发送返回EPERM | 缺少向目标发信号的权限 | 记录权限失败,检查部署身份与命名空间条件 |
| 发送返回ESRCH | 绑定目标已不再可接收该请求 | 转入退出观察或已结束处理,不重新按旧PID找目标 |
| 返回EBADF | 传入的不是有效PID文件描述符 | 排查提前关闭、误传句柄或并发所有权问题 |
| 返回EINVAL | 信号、flags或命名空间等参数条件不满足 | 按对应接口文档定位,不盲目重复请求 |
| 接口不可用 | 运行环境可能未提供相关系统调用 | 显式报告能力不足;降级方案重新评估身份竞争 |
pidfd 并不授予额外信号权限。目标凭据、调用方身份以及命名空间关系仍受系统规则约束。部署时也要区分“创建句柄成功”和“具有发送信号权限”两个事实,不能把前者当成后者的保证。
关闭句柄应由单一所有者执行:先撤销事件监听、停止其他线程借用,再关闭 fd 并从任务记录移除。若一个线程关闭句柄,另一个线程仍用那个整数,描述符编号也可能被本进程复用;这会重新引入另一类资源管理错误。pidfd 解决目标 PID 身份稳定性,不替应用解决本地 fd 的并发所有权。
pidfd_send_signal支持哪些内核?
man-pages 记载发送接口从 Linux 5.1 引入,pidfd_open 从 Linux 5.3 引入。若使用本文两接口组合,需要同时满足它们的运行能力与编译头文件要求;不要仅按其中一个版本判断部署条件。
用0号信号能确认服务健康吗?
不能。它不执行应用层健康检查,也不能证明下一次请求时目标仍处于同样状态。服务是否能处理业务,应由服务自己的健康协议判断。
管理器关闭pidfd会让目标退出吗?
不会。关闭句柄只是释放管理器持有的文件描述符,发送信号、观察退出和回收子进程分别是其他操作。
接口资料:https://man7.org/linux/man-pages/man2/pidfd_send_signal.2.html;https://man7.org/linux/man-pages/man2/pidfd_open.2.html;https://man7.org/linux/man-pages/man2/waitid.2.html。
Linux fanotify怎样监控目录变化并过滤事件
- 上一篇
- Linux fanotify怎样监控目录变化并过滤事件
- 下一篇
- Linux openat2 RESOLVE_BENEATH怎样限制路径不能逃逸根目录
-
- 文章 · linux | 52分钟前 | Linux timeout 防火墙规则 nftables sets flags timeout 临时封禁
- Linux nftables sets timeout怎样让临时规则自动过期
- 134浏览 收藏
-
- 文章 · linux | 55分钟前 |
- Linux ethtool ring怎样查看网卡收发环大小
- 264浏览 收藏
-
- 文章 · linux | 57分钟前 |
- Linux ip route get 怎样按源地址和网卡确认内核选路
- 171浏览 收藏
-
- 文章 · linux | 59分钟前 | Linux · 服务管理 · Linux 退出码 Restart systemd.service RestartPreventExitStatus
- Linux systemd.service RestartPreventExitStatus 怎样让指定退出码不重启
- 371浏览 收藏
-
- 文章 · linux | 1小时前 |
- Linux systemd.exec OOMScoreAdjust怎样调整服务被 OOM 选择的优先级
- 269浏览 收藏
-
- 文章 · linux | 1小时前 |
- Linux clone3 set_tid怎样为容器初始化进程设置线程 ID
- 119浏览 收藏
-
- 文章 · linux | 1小时前 | Linux 路径安全 openat2 RESOLVE_BENEATH
- Linux openat2 RESOLVE_BENEATH怎样限制路径不能逃逸根目录
- 208浏览 收藏
-
- 文章 · linux | 1小时前 |
- Linux fanotify怎样监控目录变化并过滤事件
- 484浏览 收藏
-
- 文章 · linux | 1小时前 | 网络编程 · Linux ·
- Linux io_uring multishot accept怎样持续接收连接事件
- 415浏览 收藏
-
- 文章 · linux | 1小时前 |
- Linux io_uring registered files怎样减少高频 I/O 的文件描述符开销
- 120浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 888次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 887次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 970次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 955次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 782次使用
-
- Linux vmstat 如何分辨内存抖动与磁盘等待:si、so、wa 与复测顺序
- 2026-08-30 501浏览
-
- Linux搭建vsftpdFTP服务器教程
- 2026-04-30 501浏览
-
- Shell脚本安装教程:.sh一键安装指南
- 2026-03-16 501浏览
-
- Linux清空文件内容的几种方法
- 2025-12-01 501浏览
-
- Linux命令行下载文件技巧
- 2025-11-23 501浏览
