在 Unix-ish 环境中,PID 环绕是否保证改变进程开始时间?
In Unix-ish environments, is PID wraparound guaranteed to change process start time?
上下文:
我在学术上对 tracking/identifying UNIX 进程很感兴趣,这种方式可以证明 PID wraparound。要通过 PID 开始跟踪进程,我需要能够在系统上最终识别它。
因此,我需要一个函数,get_identity
,它接受一个 PID,并且只有 returns 一旦它确定了该 PID 的系统范围的唯一标识。该函数应适用于所有或大多数 POSIX 兼容系统。
我所知道的过程 table 中唯一的 immutable 值是 PID 和开始时间。但是,以下情况会带来问题:
- 用户调用
get_identity(pid)
get_identity
读取 in seconds-since-the-epoch of pid
,如果存在,returns希望唯一的元组 [pid, starttime]
(这是优秀的 psutil
Python 库认为 "unique enough",所以它应该非常健壮)。
- 在该调用的一秒内,系统发生 PID 环绕,
pid
被回收。
[pid, starttime]
元组现在引用的进程与调用 get_identity
时出现的进程不同。
虽然极 不可能 发生 PID 回绕并在其被识别后的一秒内重新使用选定的 PID,但这并非 不可能。 . .对吧?
问题:
- 在 UNIX/POSIX-compliant 系统上是否可以保证 PID 的开始时间在重复使用同一 PID 值时会有所不同?
- 如果不是,我如何才能唯一地标识一个容易出现回绕的系统上的进程?
我尝试过的:
- 我可以在检查目标进程后简单地
sleep
一秒钟。如果 sleep
之后的开始时间(以秒为单位)相同,那么它要么是我开始观察的同一个进程,要么 PID 已环绕到另一个不同的进程,但系统无法区分。如果开始时间改变了,我可以 return 一个错误,或者重新开始。但是,这需要我的识别功能在 returning 之前最多等待 1 秒,这并不理想。
times()
returns 时钟滴答中的值,我可以将其转换为秒。假设进程的开始时间以秒为单位基于 times
使用的相同时钟,并假设所有 UNIX 使用相同的舍入逻辑从 clock ticks -> fractional seconds -> whole seconds
转换,理论上我可以使用此信息将上述解决方法中 sleep
的持续时间缩短到下一个 "full second boundary according to the process table" 之前的时间。但是,最坏情况下的睡眠时间仍将近1秒,所以这并不理想。
- 在 Linux 上,我可以从
/proc/$pid/stat
文件中获取以 jiffies 为单位的开始时间(或 CPU 滴答,对于旧的 Linuxes)。有了这些信息,我的程序可以稍等片刻(即?),再次检查开始时间,如果相同,则确定身份。这正确地解决了我的问题(1 jiffy + overhead 是足够快的运行时间),但仅限于 Linux;其他 UNIX 平台可能没有 /proc
。在 BSD 上,该信息是 available via the kvm
subsystem or via sysctl
s。在其他 Unix 上。 . .谁知道?我需要开发多个特定于平台的实现来收集这些数据——这是我希望避免的事情。
由于 PID 的分配和 proc table 管理通常没有任何标准定义,所以实际上不可能以 portable 方式做你想做的事。
您将需要按照您所说的去做并开发多个特定于平台的实现来收集有关进程的足够信息以确定每个进程的唯一标识。
另一方面,如果您不需要在进程启动时实时获取此信息,并且当它们仍在 运行ning 时,您可以在大多数 unix-y 系统上简单地打开进程会计,并保证系统 运行 每个流程的唯一和完整记录。处理会计文件也没有标准化,但会有头文件定义其记录格式,并且每种系统上应该有工具可以以各种方式处理和汇总会计文件。
保证 PID 环绕。你永远不会得到两个具有相同 pid 的进程。
上下文:
我在学术上对 tracking/identifying UNIX 进程很感兴趣,这种方式可以证明 PID wraparound。要通过 PID 开始跟踪进程,我需要能够在系统上最终识别它。
因此,我需要一个函数,get_identity
,它接受一个 PID,并且只有 returns 一旦它确定了该 PID 的系统范围的唯一标识。该函数应适用于所有或大多数 POSIX 兼容系统。
我所知道的过程 table 中唯一的 immutable 值是 PID 和开始时间。但是,以下情况会带来问题:
- 用户调用
get_identity(pid)
get_identity
读取 in seconds-since-the-epoch ofpid
,如果存在,returns希望唯一的元组[pid, starttime]
(这是优秀的psutil
Python 库认为 "unique enough",所以它应该非常健壮)。- 在该调用的一秒内,系统发生 PID 环绕,
pid
被回收。 [pid, starttime]
元组现在引用的进程与调用get_identity
时出现的进程不同。
虽然极 不可能 发生 PID 回绕并在其被识别后的一秒内重新使用选定的 PID,但这并非 不可能。 . .对吧?
问题:
- 在 UNIX/POSIX-compliant 系统上是否可以保证 PID 的开始时间在重复使用同一 PID 值时会有所不同?
- 如果不是,我如何才能唯一地标识一个容易出现回绕的系统上的进程?
我尝试过的:
- 我可以在检查目标进程后简单地
sleep
一秒钟。如果sleep
之后的开始时间(以秒为单位)相同,那么它要么是我开始观察的同一个进程,要么 PID 已环绕到另一个不同的进程,但系统无法区分。如果开始时间改变了,我可以 return 一个错误,或者重新开始。但是,这需要我的识别功能在 returning 之前最多等待 1 秒,这并不理想。 times()
returns 时钟滴答中的值,我可以将其转换为秒。假设进程的开始时间以秒为单位基于times
使用的相同时钟,并假设所有 UNIX 使用相同的舍入逻辑从clock ticks -> fractional seconds -> whole seconds
转换,理论上我可以使用此信息将上述解决方法中sleep
的持续时间缩短到下一个 "full second boundary according to the process table" 之前的时间。但是,最坏情况下的睡眠时间仍将近1秒,所以这并不理想。- 在 Linux 上,我可以从
/proc/$pid/stat
文件中获取以 jiffies 为单位的开始时间(或 CPU 滴答,对于旧的 Linuxes)。有了这些信息,我的程序可以稍等片刻(即?),再次检查开始时间,如果相同,则确定身份。这正确地解决了我的问题(1 jiffy + overhead 是足够快的运行时间),但仅限于 Linux;其他 UNIX 平台可能没有/proc
。在 BSD 上,该信息是 available via thekvm
subsystem or viasysctl
s。在其他 Unix 上。 . .谁知道?我需要开发多个特定于平台的实现来收集这些数据——这是我希望避免的事情。
由于 PID 的分配和 proc table 管理通常没有任何标准定义,所以实际上不可能以 portable 方式做你想做的事。
您将需要按照您所说的去做并开发多个特定于平台的实现来收集有关进程的足够信息以确定每个进程的唯一标识。
另一方面,如果您不需要在进程启动时实时获取此信息,并且当它们仍在 运行ning 时,您可以在大多数 unix-y 系统上简单地打开进程会计,并保证系统 运行 每个流程的唯一和完整记录。处理会计文件也没有标准化,但会有头文件定义其记录格式,并且每种系统上应该有工具可以以各种方式处理和汇总会计文件。
保证 PID 环绕。你永远不会得到两个具有相同 pid 的进程。