有没有办法在Linux系统上暂停正在运行的进程并稍后恢复?


37

我必须在计算机上复制文件。数据非常大。现在,服务器需要正常服务,并且通常在这些服务器上有特定的繁忙时间范围。那么,是否有一种方法可以运行这种命令,如果服务器繁忙时间会暂停进程,而当服务器超出该范围时会恢复进程?

预期结果

cp src dst

if time between 9:00-14:00 pause process
After 14:00 resume cp command.

22
rsync的可以恢复部分转移
托尔比约恩Ravn的安德森

2
您是否需要将实际数据复制为备份?如果没有,您可以cp -al用来建立硬链接服务器场吗?或使用支持使用写时复制功能的块级reflink的文件系统,使用cp -a --reflink=auto?BTRFS和ZFS支持同一物理设备中的副本。
彼得·科德斯

9
src在9:00和14:00之间是否有任何文件更改?如果是这样,简单地暂停并恢复该cp过程可能会导致文件损坏。rsynctimeout命令结合使用可能会更好。
Mark Plotnick

从文件复制到哪里?这是虚拟系统吗?什么是源文件系统?复制的目的是什么?
Braiam

@Braiam Im使用rsync,并将文件从远程复制到本地计算机。我只是在这里使用cp命令作为示例btw
Sollosa

Answers:


7

是的,你需要

acquire the process id of the process-to-paus (PS), then do
$> kill -SIGSTOP <pid>

然后,该过程将显示状态为“ T”(PS)。继续做一个

$> kill -CONT <pid>

祝好运!


77

您可以通过发送SIGSTOP信号来暂停进程的执行,然后再通过发送SIGCONT来恢复进程。

假设您的工作量是一个单一的过程(不分叉助手在后台运行),则可以使用以下方法:

# start copy in background, store pid
cp src dst &
echo "$!" >/var/run/bigcopy.pid

然后,当繁忙时间开始时,向其发送SIGSTOP:

# pause execution of bigcopy
kill -STOP "$(cat /var/run/bigcopy.pid)"

稍后,当服务器再次空闲时,将其恢复。

# resume execution of bigcopy
kill -CONT "$(cat /var/run/bigcopy.pid)"

您需要将其计划为在特定时间执行,可以使用cron或systemd计时器之类的工具(或各种其他类似工具)来安排此时间。您可以选择监视服务器(也许查看服务器日志中的平均负载,CPU使用率或活动),而不是根据时间间隔进行调度,以决定何时暂停/恢复副本。

您还需要管理PID文件(如果使用一个文件),请在暂停之前确保副本实际上仍在运行,可能需要在副本完成后通过删除pidfile进行清理等。

换句话说,您需要更多解决方案来确保可靠性,但是您正在寻找使用这些SIGSTOP和SIGCONT信号来暂停/恢复进程执行的基本思想。



1
也许提醒您,您应该非常小心'/var/run/bigcopy.pid'仍然引用与您认为相同的过程。随机停止系统上的其他进程可能不是理想的。我知道没有安全的方法可以确保pid引用您认为确实可以使用的程序...
Evan Benn

@EvanBenn是的,我的意思是“确保在暂停之前,副本实际上仍在运行”,尽管您的意思肯定比这更明确!是的,检查PID本质上是y,所以有时实际上不可能100%可靠地做到这一点……
filbranden

@cat不是,进程不能阻止SIGSTOP。请参阅第一条评论的链接:“ SIGSTOP是像SIGKILL这样的不可阻塞的信号”(或者只是在Google上搜索,就会看到这种情况。)
filbranden

76

除了暂停该过程之外,您还可以将其设置为较低的优先级:

renice 19 "$pid"

将赋予它最低的优先级(最高的优先级),这样该进程会将CPU大部分时间分配给其他需要它的进程。

在Linux上,可以使用以下命令对I / O进行相同操作ionice

ionice -c idle -p "$pid"

将进程放在“ idle”类中,以便仅在没有其他程序在定义的宽限期内要求磁盘I / O时才获得磁盘时间


22
这是XY问题的典型情况。问题是如何暂停一个过程,但这不能回答问题。虽然降低优先级确实是解决实际问题的更好方法,但它不能回答问题。我将编辑问题以包括如何暂停进程以及为什么暂停可能是个问题(例如,可以在暂停时编辑文件)。
MechMK1

22
@DavidStockinger,从技术上讲,此答案告诉如何在OS(CPU,I / O调度程序)繁忙时(即使一次仅几分之一秒)使OS暂停进程。其他答案已经介绍了如何手动暂停该过程。此解决方案无法解决在复制文件时修改文件的问题。
StéphaneChazelas,

5
更改I / O优先级并不总是最好的解决方案。如果从旋转磁盘进行复制,则可能仍会在每个高优先级请求之前引发搜索,如果您完全暂停了低优先级操作,则不会产生搜索。
马克

2
较低的优先级甚至不能解决问题。即使该盒子完全闲置了几秒钟或几分钟,这并不意味着一个庞大的复制过程将不会吸引文件系统缓存中的所有内容。只要有再次负载,这将是非常缓慢的分页一切回来。
R.,

2
@DavidStockinger处理XY问题的首选方法是给出正确的解决方案,即使这不是问题所要的。当您知道问题中描述的方法是错误的时,那么好的答案并不会给出错误的方法,而是会提出一种更好的方法。
terdon

8

在这种情况下,请使用rsync,而不必理会cp。有参数来限制带宽,或者可以杀死/停止并在以后启动,以某种方式将继续,它离开了Google rsync示例


3

如果要通过中断正在运行的进程来执行此操作,建议您使用Screen程序。我已经有一段时间没有使用Linux了,但是IIRC只是暂停该命令并在以后恢复它,这使您很容易受到攻击,如果您不小心注销了,将无法继续进行会话。

通过屏幕,我相信您可以中断会话,然后分离它并注销。之后,您可以返回并重新加入该会话。您可能需要使用它,但是它使会话更加健壮。

您还可以注销并回家,然后远程登录,重新连接到您在办公室开始使用的系统,并在晚上恢复使用,然后在第二天上班时再次使用它。


我已经在用tmux了。但是我正在编写一个脚本,该脚本应该具有自我意识,或者最好是具有环境意识,因此,如果服务器流量增加,它将停止运行,并在正常情况下继续运行。
Sollosa

0

如果您的外壳支持(几乎所有功能都支持),则可以按^ Z(Ctrl + Z)轻松地将SIGTSTP信号发送到前台任务,然后继续fg(在前台)或bg(在后台)继续执行。

如果您对多个任务执行此操作并想稍后返回它们jobs,则可以使用command,然后返回with fg/bg %#,其中#是作业括号中给出的数字。

请记住,这SIGTSTPSIGSTOP(在所有其他答案中都使用过)有所不同,最重要的原因是它可以忽略(但我没有看到一个程序会忽略它sl)。在StackOverflow上的此答案中可以找到更多详细信息。


惊讶的是没有答案提到这一点。
大街

Ty Ave,我知道这个多任务处理技巧。但是要做到这一点,需要在终端上,而我要构建一个脚本,该脚本可以自行完成工作,而无需花费几天的时间。
索洛萨

@Sollosa对于具有相同问题并可以访问终端的其他人可能很有用。
大街

我同意。很高兴认识您:)
Sollosa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.