在 Unix-ish 环境中,PID 环绕是否能保证更改进程启动时间?

Zac*_*c B 5 c unix linux pid process

语境:

在学术上,我对以防止PID 环绕的方式跟踪/识别 UNIX 进程感兴趣。要开始通过 PID 跟踪进程,我需要能够在系统上最终识别它。

因此,我需要一个函数 ,get_identity它接受 PID,并且只有在确定了该 PID 的系统范围唯一标识后才返回。该函数应该适用于所有或大多数符合 POSIX 标准的系统。

据我所知,进程表中唯一不可变的值是 PID 和启动时间。然而,以下场景会带来问题:

  1. 用户来电get_identity(pid)
  2. get_identity读取 的开始时间(以秒为单位)pid(如果存在),并返回希望唯一的元组[pid, starttime](这是优秀的psutilPython 库认为“足够唯一”的内容,因此它应该非常强大)。
  3. 在该调用的一秒内,系统上会发生 PID 环绕,并被pid回收。
  4. [pid, starttime]元组现在引用的进程与调用时出现的进程不同get_identity

虽然发生 PID 环绕并在识别后一秒内重新使用所选 PID 的可能性极小,但这并非不可能。。。正确的?

问题:

  • 在 UNIX/POSIX 兼容系统上,是否可以保证在回绕导致的同一 PID 值的重复使用之间 PID 的开始时间会有所不同?
  • 如果不是,我如何才能唯一地识别容易出现回绕的系统上的进程?

我尝试过的:

  • sleep在检查目标进程后我可以简单地花一秒钟。如果 后的启动时间(以秒为单位)相同sleep,则它要么是我开始观看的同一进程,要么 PID 已转换为不同的进程,但系统无法区分。如果开始时间发生了变化,我可以返回错误,或者重新开始。然而,这需要我的识别功能最多等待1秒才能返回,这并不理想。
  • times()返回以时钟周期为单位的值,我可以将其转换为秒。假设进程的启动时间(以秒为单位)基于times使用的相同时钟,并且假设所有 UNIX 使用相同的舍入逻辑从 进行转换,理论上我可以使用此信息来减少上述解决方法中clock ticks -> fractional seconds -> whole seconds的持续时间sleep到下一个“根据流程表的完整秒边界”的时间。然而,最坏情况下的睡眠时间仍然接近 1 秒,因此这并不理想。
  • 在 Linux 上,我可以从文件中获取以 jiffies(或 CPU 滴答,对于旧 Linux)为单位的启动时间/proc/$pid/stat。有了这些信息,我的程序可以等待一瞬间(即?),再次检查开始时间,如果相同,则确定身份。这正确地解决了我的问题(1 jiffy + 开销是足够快的运行时),但仅限于 Linux;其他 UNIX 平台可能没有/proc。在 BSD 上,该信息可通过kvm子系统或通过sysctls获得。在其他 Unix 上。。。谁知道?我需要开发多个特定于平台的实现来收集这些数据——这是我希望避免的。

Gre*_*ods 1

由于 PID 的分配和 proc 表管理通常没有由任何标准定义,因此实际上不可能以可移植的方式执行您想要的操作。

您将需要按照您所说的进行操作,并开发多个特定于平台的实现,以收集有关流程的足够信息,以确定每个流程的唯一标识。

另一方面,如果您在进程启动时以及进程仍在运行时不需要实时获取此信息,则在大多数 UNIX-Y 系统上,您可以简单地打开进程记帐并获得有保证的唯一且完整的记录。系统运行过的每个进程。流程会计文件也没有标准化,但是会有定义其记录格式的头文件,并且每种类型的系统上都应该有可以以各种方式处理和汇总会计文件的工具。