【问题标题】:In Unix-ish environments, is PID wraparound guaranteed to change process start time?在 Unix-ish 环境中,PID 环绕是否可以保证更改进程开始时间?
【发布时间】:2017-01-22 12:11:37
【问题描述】:

上下文:

我在学术上对跟踪/识别 UNIX 进程很感兴趣,这种方法可以证明是针对 PID wraparound 的。要开始通过 PID 跟踪进程,我需要能够在系统上最终识别它。

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

我知道的进程表中唯一不可变的值是 PID 和开始时间。但是,以下情况会带来问题:

  1. 用户致电get_identity(pid)
  2. get_identity 读取pid 的开始时间in seconds-since-the-epoch,如果它存在,并返回希望唯一的元组[pid, starttime](这就是优秀的psutil Python 库认为“足够独特”,因此它应该非常健壮)。
  3. 在调用的一秒内,系统上会发生 PID 回绕,pid 被回收。
  4. [pid, starttime] 元组现在指的是与调用 get_identity 时不同的进程。

虽然 PID 环绕发生并在其被识别后的一秒钟内重新使用选定的 PID 是非常不可能,但它并非不可能。 . .对吧?

问题:

  • 在 UNIX/POSIX 兼容系统上,是否保证 PID 的开始时间在重复使用相同 PID 值时会有所不同?
  • 如果不是,我如何才能唯一地标识易环绕系统上的进程?

我的尝试:

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

【问题讨论】:

  • 坦率地说,我认为你已经被灌输了。如果进程以每秒超过 2^16 的速率生成,我绝对希望 PID+starttime 冲突是可能的。内核人员必须有一个具体的理由来扭曲 starttime 值以使 PID+starttime 独一无二,我希望 starttime 准确性被认为更重要。
  • @zwol 不同意您的总体结论,但请记住,PID 环绕发生的频率可能远高于每秒 2^16 次。当然,这仍然不太可能,但考虑一个已经有 2^16-4 个长期运行进程的系统 - 然后每 4 个分叉就会发生 PID 环绕...
  • @twalberg 哦,好点,我什至没有想到。
  • 您应该查看Proc connector。有了它,您可以订阅系统上发生的所有进程事件,包括fork() 和exec()。
  • proc 连接器看起来超级有用,谢谢!不幸的是,它仅适用于 Linux。知道这样的跨平台吗?

标签: c linux unix process pid


【解决方案1】:

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

您需要按您说的做,并开发多个特定于平台的实现,以收集有关流程的足够信息,以确定每个流程的唯一身份。

另一方面,如果您不需要在进程启动时实时获取这些信息,并且当它们仍在运行时,您可以在大多数 unix-y 系统上,只需打开进程记帐并保证唯一且系统运行过的每一个进程的完整记录。流程记账文件也没有标准化,但会有头文件定义其记录格式,并且每种类型的系统上都应该有工具,可以对记账文件进行各种处理和汇总。

【讨论】:

    【解决方案2】:

    PID 环绕是有保证的。你永远不会得到两个具有相同 pid 的进程。

    【讨论】:

    • 对不赞成票的评论将不胜感激,主要是因为不同的 unice 有不同的方法来确保它,这不仅必须确保,而且要有效地确保。
    • 这并没有回答问题,这是关于 PID 环绕对进程启动时间的影响。 PID 唯一性是没有问题的; 过程唯一性是我试图更好地识别的。
    猜你喜欢
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 2017-03-05
    • 2022-08-13
    • 2010-12-20
    • 2014-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多