【问题标题】:How to set process ID in Linux for a specific program如何在 Linux 中为特定程序设置进程 ID
【发布时间】:2013-08-08 09:35:17
【问题描述】:

我想知道是否有某种方法可以强制在运行某个应用程序之前将某个特定进程 ID 用于 Linux。我需要提前知道进程 ID。

【问题讨论】:

  • 闻起来像 XY 问题。为什么需要提前 pid?
  • 根据我对 Linux 和 Unices 的总体了解,如果你能做到这一点,我会感到惊讶,但是一旦给定进程运行,有很多方法可以计算出它的 PID。也许你应该解释你想做什么并就替代方案提出建议。
  • 简短的回答是否定的。
  • 你真的需要提前设置PID,还是将不透明生成的PID传递给另一个进程就足够了(例如从父进程中fork的返回值或@之间987654323@ 和exec* 在子进程中甚至在exec*) 之后?

标签: linux process set


【解决方案1】:

实际上,有一种方法可以做到这一点。由于内核 3.3 设置了 CONFIG_CHECKPOINT_RESTORE(在大多数发行版中设置),因此 /proc/sys/kernel/ns_last_pid 包含内核生成的最后一个 pid。所以,如果你想为 fork 的程序设置 PID,你需要执行这些操作:

  1. 打开 /proc/sys/kernel/ns_last_pid 并获取 fd
  2. 用 LOCK_EX 锁定它
  3. 写入 PID-1
  4. 分叉

瞧!孩子将拥有您想要的 PID。 另外,不要忘记解锁(使用 LOCK_UN 锁定)并关闭 ns_last_pid。

你可以在我的博客here查看C代码。

【讨论】:

  • c 代码是 criu 项目的一部分。并且文件 /proc/sys/kernel/ns_last_pid 并不存在于所有系统中。因此,该代码不适用于 ubuntu。有什么办法可以让它在 ubuntu 上运行?
  • @hebbo 代码应该可以在相当新的 ubuntu 上运行。在 14.04 和 14.10 测试。
  • 我喜欢这个想法,但在大多数实际情况下这是一个糟糕的 hack。 :-D
【解决方案2】:

正如许多人已经建议的那样,您不能直接设置 PID,但通常 shell 可以知道哪个是最后一个分叉的进程 ID。

例如,在 bash 中,您可以在后台启动一个可执行文件(附加 &)并在变量 $! 中找到它的 PID。 示例:

$ lsof >/dev/null &
[1] 15458
$ echo $!
15458

【讨论】:

    【解决方案3】:

    在 CentOS7.2 上,您可以简单地执行以下操作:

    假设您要执行 PID 为 1894 的 sleep 命令。

    sudo echo 1893 > /proc/sys/kernel/ns_last_pid; sleep 1000
    

    (但是,请记住,如果偶然在 echo 和 sleep 命令之间的极短时间执行另一个进程,您最终可能会得到 1895+ 的 PID。我已经对其进行了数百次测试并且它我从来没有发生过。如果你想保证 PID,你需要在写入文件后锁定文件,执行睡眠,然后按照上面 Ruslan 的回答中的建议解锁文件。)

    【讨论】:

      【解决方案4】:

      没有办法强制为进程使用特定的 PID。正如Wikipedia 所说:

      进程 ID 通常是按顺序分配的,从 0 并上升到最大值,该最大值因系统而异。 一旦达到此限制,分配将在 300 处重新开始,然后再次 增加。在 Mac OS X 和 HP-UX 中,分配在 100 处重新开始。但是, 对于这个和随后的传递,仍然分配给进程的任何 PID 被跳过

      【讨论】:

      • 感谢您提供有用的答案。事情是我试图根据进程 ID 生成一些 ICMP 数据包回复,为此我需要一些基于原始进程的 PID 的校验和。所以这就是为什么我真的要提前知道这个 PID 以便生成正确的校验和。这意味着,我应该根据请求实时构建数据包。但是,如果我知道 PID,这应该更容易并且可以在之前准备好。我认为唯一的选择是破解/修改 linux 源代码,以便在某些特定情况下提供特定的 PID。
      • 你可以在启动时提前启动一些进程,然后让它们execve成为适当的程序(在一些众所周知的地方注册了它们的pid之后)。我肯定会避免为此破解内核。
      • 谢谢,最后我会根据输入数据包实时创建数据包响应。因此,我根据从原始数据包中提取的进程 ID 获得了校验和,并为客户端应用程序提供了一些延迟,以便有时间构建数据包并回复。现在这对我来说非常有效,所以最终不需要任何黑客攻击。
      【解决方案5】:

      您可以反复调用fork() 来创建新的子进程,直到获得具有所需PID 的子进程。记得经常打电话给wait(),否则你会很快达到每个用户的进程限制。

      此方法假定操作系统按顺序分配新的 PID,例如,情况似乎就是这样。在 Linux 3.3 上。

      ns_last_pid 方法相比的优势在于它不需要root 权限。

      【讨论】:

        【解决方案6】:

        linux 系统上的每个进程都是由 fork() 生成的,所以应该没有办法强制使用特定的 PID。

        【讨论】:

        • 除了由内核神奇地启动的少数进程:/sbin/init 可能还有/sbin/modprobe 等等...(更不用说vfork 作为fork 的变体)
        猜你喜欢
        • 2014-11-02
        • 1970-01-01
        • 2014-11-03
        • 1970-01-01
        • 1970-01-01
        • 2014-08-25
        • 2014-07-14
        • 1970-01-01
        • 2018-07-03
        相关资源
        最近更新 更多