可以在 linux 中暂时冻结进程吗?

Pal*_*asz 55 linux freeze process

我想知道是否有办法在一定时间内冻结任何进程?

我的意思是:一个应用程序(可能以 root 身份运行)是否有可能暂停另一个已经运行的进程(任何进程,包括 GUI 和命令行)的执行,然后再恢复它?换句话说,我不希望 linux 调度程序在一定时间内调度某些进程。

all*_*tic 86

这里

两种信号可以暂停进程的执行。一种是“优雅”,一种是“有力”。

“优雅”的是SIGTSTP,它的目的是“很好地”询问进程,如果它愿意,请暂停执行,直到它收到SIGCONT. 在 的情况下SIGTSTP,进程可以忽略 SIGTSTP 并继续执行,因此这需要设计用于处理 SIGTSTP 的程序的合作。

“强制”的是SIGSTOP,其目的是挂起与该进程关联的所有用户空间线程。进程忽略SIGSTOP它和忽略它一样不可能SIGKILL(后者强行杀死进程)。

要发送任意信号,包括此处提到的任何信号,您可以使用诸如killkillall、 或 之类的程序pkill;或使用系统调用kill(2)。有关上述任何一项的平台/体系结构/版本相关的详细信息和勘误表,请参阅操作系统的联机帮助页。请注意,所有这些命令和系统调用中的“kill”一词用词不当。这些命令并非专门用于终止进程。他们可以通过发送某些信号做到这一点;但信号也可用于终止进程以外的功能。例如,SIGSTOP只暂停进程,它只是可以通过这种方式发送的几个信号之一。

要添加一段时间后自动恢复进程的条件,您将需要使用某种仍在运行的监控进程并设置一个计时器以唤醒监控进程,然后kill(2)再次调用并向SIGCONT停止的进程发送信号,以请求内核恢复执行。请注意,Linux 具有多种准确度和精确度不同的计时机制;此外,如果您的系统非常繁忙,您的监控进程可能要在其计时器到期后很久才会被唤醒,因此唤醒可能会延迟。

如果你依赖于挂起的进程的中止和恢复的非常准确的精度,您可能需要通过实时权限运行监控程序(见本手册页sched_setscheduler(2)的信息,有关使您的过程实时)。您还可以使用高分辨率计时器,这是 Linux 内核的一项功能(仅当您的硬件提供支持时才可用)与实时调度相结合,以获得非常准确的亚毫秒级计时精度,然后唤醒并发送信号以非常快速地恢复被监控的进程。

您没有说明您愿意使用哪些技术来实现这一点。至少,您至少需要 bash 脚本,尽管您将无法通过这种方式获得非常细粒度的计时。这是一个bash“脚本”(未经测试,所以请小心),它只是您查询的概念证明。如果您需要精确计时,则必须编写一个程序,可能使用 C/C++ 或其他本地语言,并使用实时调度和 hrtimers。

#!/bin/bash
#This is the process you want to suspend.
screen -mdS child bash -c "cat /dev/urandom | base64"
#This is the process ID of the child process
THEPID=$(screen -list | grep child | cut -f1 -d'.' | sed 's/\W//g')
#Send SIGSTOP to the child process.
kill -SIGSTOP ${THEPID}
#Now it is suspended. This process will sleep for 10 seconds asynchronously, then resume the process.
screen -mdS monitor bash -c "sleep 10; kill -SIGCONT ${THEPID}"
Run Code Online (Sandbox Code Playgroud)

请注意,脚本将结束,控制脚本将终止,但由于screen控制监视器进程,它将在后台继续运行 10 秒(基于传递给 的参数sleep),然后唤醒并继续子进程。但这将在控制脚本结束后很长时间。如果您想同步等待时间过去,只需省略第二次调用screen并将 sleep 和 kill 硬编码到控制脚本中。

您可以通过运行来测试该进程实际上是否挂起

screen -rS child

启动此脚本后。您不会在控制台上看到任何内容。然后在计时器到期(10 秒)后,它将用 base64 数据(0-9 和 AF 的随机字符)淹没您的屏幕。按 Ctrl+C 退出。


小智 17

是的,您可以通过向进程发送STOP信号以将其挂起,然后发送CONT以继续来实现。

用法:

kill -STOP <pid>

kill -CONT <pid>
Run Code Online (Sandbox Code Playgroud)


小智 12

如果您对“冻结”有一个适当宽松的定义,您可以查看该renice命令。

Renice 允许您更改正在运行的进程的调度优先级。

正常的进程 nice 值为 0。增加 nice 值会使进程更好,如“你为什么不先走”。虽然降低 nice 值会使过程变得不那么好,例如“让开,我很着急”。nice 值范围是 -20 到 19。

任何人都可以使自己的流程更好。只有 root 可以使进程变得不那么好或改变另一个用户进程的好。

如果您将进程 nice 值设置为 19,它只会在系统上没有其他任何内容时运行。

这是在我的本地 linux 机器上运行的示例。

使用ps -l并查看 NI 列以查看进程不错的值。

-> ps -l
FS UID PID PPID C PRI NI ADDR SZ WCHAN TTY CMD
0 S 29190 402 31146 0 75 0 - 16547 等待 pts/0 bash
0 T 29190 1105 402 0 75 0 - 23980 完成点/0 vim
0 R 29190 794 402 0 76 0 - 15874 - pts/0 ps

运行renice +10在Vim进程使其以较低的优先级运行。

-> 雷尼斯 +10 -p 1105
1105:旧优先级 0,新优先级 10

-> ps -l
FS UID PID PPID C PRI NI ADDR SZ WCHAN TTY CMD
0 S 29190 402 31146 0 76 0 - 16547 等待 pts/0 bash
0 T 29190 1105 402 0 95 10 - 23980 完成点/0 vim
0 R 29190 1998 402 0 78 0 - 15874 - pts/0 ps

假设您可以将“冻结”扩展为“不打扰系统上的其他人”,您可以编写如下脚本:

renice 20 -p <感兴趣的pid>
sleep <一定的时间>
renice 0 -p <感兴趣的pid>

(记住以root身份运行它)。


请注意,我对上述ps -l输出采取了一些自由措施,以使有趣的列很好地显示在蓝色小框中:)