【问题标题】:PHP: How can I uniquely identify a process on linux?PHP:如何在 linux 上唯一标识一个进程?
【发布时间】:2014-01-30 13:39:56
【问题描述】:

我正在使用 php 进程在后台发送电子邮件,并且我正在尝试找到一种自动恢复的方法,以防服务器出现故障或脚本发生故障以使其停止。

我的逻辑是:如果发送会话仍在运行但在 X 时间内没有发送新电子邮件,如果已经在运行,则终止该进程并启动一个新进程。

现在,我的问题在于“如果已经运行则终止进程”部分。我如何确定这个 PID 的进程与我为发送会话启动的进程相同?我无法检查名称,因为我将同时运行其中的几个。我不想杀死一个随机进程或另一个发送进程。

那么问题来了:我怎样才能唯一标识一个在linux上运行的进程呢?或者我怎样才能以某种方式标记它以使其独一无二?有没有办法从外面检查它的参数?

【问题讨论】:

  • 您可以像大多数其他软件一样创建一个 PID 文件,然后使用这个文件。 db 存储值也是可用的。如果是控制台运行 PHP 脚本,您可以使用 getmypid() 存储您的 PID,并在必要时使用此 PID 杀死。
  • 我已经有进程的PID存储在数据库中。我需要一些方法来确保这无疑是发送会话的正确过程。
  • 如果您的脚本作为控制台 PHP 脚本运行,您可以确定。
  • 即使在服务器关闭之后?脚本可以运行数天,甚至数周;我想消除服务器关闭导致 PID 重新分配给其他进程的可能性。
  • 好吧,我没想到服务器会关闭...你猜不是。我怀疑是否有办法获得持久的唯一进程 ID。哦,但是顺便说一句,PHP 有一个最大执行时间。也许将其用作防止僵尸进程的更好方法?

标签: php linux


【解决方案1】:

与 cmets 中建议的不同,由于 PID 重用(由于唯一 PID 的数量有限,通常为 32768 而加剧),PID 不足以唯一标识进程。但是,如果您将 pid 和进程的开始时间结合起来,那在实践中应该是足够独特的。并且开始时间内核滴答记录在 /proc/$pid/stat 中,考虑到这一点,您可以像这样制作一个独特的哈希:

function unique_hash_pid(int $pid): string {
    return $pid . ':' . (explode ( ' ', file_get_contents ( '/proc/' . $pid . '/stat' ) ) [21]);
}

(我想象一个进程启动,然后被 PHP 唯一标识,然后退出,然后另一个进程启动,并被重新分配给完全相同的 pid,所有这些都在一个内核滴答声中的可能性是......实际上零。因此这个哈希值应该是唯一的。如果有人对此进行了实验室测试,请告诉我!)

但是,要知道这个函数不考虑重启,并且可能会在重启之间为 2 个完全不同的进程产生相同的哈希(如果在 2 次重启之间的完全相同的内核滴答上启动相同的 pid。我想这很常见用于启动脚本)

【讨论】:

    【解决方案2】:

    由于 pid 重用,Pid 不能唯一标识一个进程。出于同样的原因,元组 (pid, command) 不能用作标识符。元组(pid,进程开始时间)也没有用,因为进程开始时间似乎很脆弱,并且例如由于 NTP 时间重置(和其他原因?)而发生变化,并且无法将更改的内容用作标识符。

    但是,要真正唯一地标识一个过程,我们可以让它们自己区分。例如,在 PHP 中,函数 cli_set_process_title [1] 可用于更改进程标题。如果我们在进程标题前添加一个随机数并将这个随机数与 pid 一起存储,我们稍后可以区分重用相同 pid 但具有不同随机数的进程,以及在标题中具有相同 pid 和相同随机数的进程.

    (其实现在nonce已经足够识别进程了,pid也不是必须的,不过保存pid还是有用的,我们就不用在进程列表中搜索进程了。)

    [1]https://www.php.net/manual/en/function.cli-set-process-title.php

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-26
      • 2018-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-10
      相关资源
      最近更新 更多