我想知道是否有某种方法可以强制在运行某个应用程序之前将某些特定的进程 ID 用于 Linux。我需要提前知道进程 ID。
6 回答
实际上,有一种方法可以做到这一点。由于内核 3.3 设置了 CONFIG_CHECKPOINT_RESTORE(在大多数发行版中设置),因此 /proc/sys/kernel/ns_last_pid 包含内核生成的最后一个 pid。因此,如果要为分叉程序设置 PID,则需要执行以下操作:
- 打开 /proc/sys/kernel/ns_last_pid 并获取 fd
- 用 LOCK_EX 蜂拥而至
- 写PID-1
- 叉
瞧!孩子将拥有您想要的 PID。另外,不要忘记解锁(使用 LOCK_UN 锁定)并关闭 ns_last_pid。
您可以在我的博客上查看 C代码。
正如许多人已经建议的那样,您不能直接设置 PID,但通常 shell 可以知道哪个是最后一个分叉的进程 ID。
例如,在 bash 中,您可以在后台启动一个可执行文件(附加&
)并在变量 中找到它的 PID $!
。例子:
$ lsof >/dev/null &
[1] 15458
$ echo $!
15458
在 CentOS7.2 上,您可以简单地执行以下操作:
假设您要执行 PID 为 1894 的 sleep 命令。
sudo echo 1893 > /proc/sys/kernel/ns_last_pid; sleep 1000
(但是,请记住,如果在 echo 和 sleep 命令之间的极短的时间内执行另一个进程,您最终可能会得到 1895+ 的 PID。我已经对其进行了数百次测试,但从未发生过对我来说。如果你想保证 PID,你需要在写入文件后锁定文件,执行睡眠,然后按照上面 Ruslan 的回答中的建议解锁文件。)
没有办法强制对进程使用特定的 PID。正如维基百科所说:
进程 ID 通常按顺序分配,从 0 开始并上升到最大值,该最大值因系统而异。一旦达到此限制,分配将在 300 处重新开始并再次增加。在 Mac OS X 和 HP-UX 中,分配在 100 处重新开始。但是,对于本次和后续传递,任何仍分配给进程的 PID 都将被跳过
您可以反复调用fork()
以创建新的子进程,直到获得具有所需 PID 的子进程。请记住经常调用wait()
,否则您将很快达到每个用户的进程限制。
此方法假定操作系统按顺序分配新的 PID,这似乎是这种情况。在 Linux 3.3 上。
该方法的优点ns_last_pid
是它不需要root权限。
linux 系统上的每个进程都是由fork()生成的,因此应该没有办法强制使用特定的 PID。