Gibt es eine Möglichkeit, einen laufenden Prozess auf Linux-Systemen anzuhalten und später fortzusetzen?

37

Ich muss Dateien auf eine Maschine kopieren. Und die Daten sind immens groß. Jetzt müssen Server normal arbeiten, und normalerweise gibt es einen bestimmten Bereich an geschäftigen Stunden. Gibt es eine Möglichkeit, solche Befehle so auszuführen, dass der Server den Prozess anhält, wenn er überlastet ist, und ihn fortsetzt, wenn er diesen Bereich verlässt?

Vorgesehenes Ergebnis

cp src dst

if time between 9:00-14:00 pause process
After 14:00 resume cp command.
Sollosa
quelle
22
rsync kann teilweise Übertragungen wieder aufnehmen
Thorbjørn Ravn Andersen
2
Haben Sie benötigen die aktuellen Daten als Backup kopiert werden? Wenn nicht, können Sie cp -aleine Hardlink-Farm erstellen? Oder verwenden Sie ein Dateisystem, das Block-Level-Reflinks mit Copy-on-Write unterstützt cp -a --reflink=auto. BTRFS und ZFS unterstützen dies für Kopien innerhalb desselben physischen Geräts.
Peter Cordes
9
srcWechselt eine der Dateien zwischen 9:00 und 14:00? Wenn dies der Fall ist cp, kann das Anhalten und Fortsetzen des Vorgangs zu beschädigten Dateien führen. Es kann besser sein, rsyncin Kombination mit dem timeoutBefehl auszuführen .
Mark Plotnick
Von und nach wo werden die Dateien kopiert? Ist das ein virtuelles System? Was ist das Quelldateisystem? Was ist der Zweck der Kopie?
Braiam
@Braiam Ich verwende rsync und kopiere Dateien von einem entfernten auf einen lokalen Rechner. Ich habe gerade den Befehl cp als Beispiel verwendet, übrigens
Sollosa

Antworten:

7

Ja, das musst du

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

Der Vorgang wird dann mit dem Status "T" (PS) angezeigt. Um fortzufahren, mache a

$> kill -CONT <pid>

Viel Glück!

gerhard d.
quelle
77

Sie können die Ausführung eines Prozesses anhalten, indem Sie ihm ein SIGSTOP-Signal senden und ihn später wieder aufnehmen, indem Sie ihm ein SIGCONT senden.

Angenommen, Ihre Workload ist ein einzelner Prozess (keine im Hintergrund ausgeführten Fork-Helfer), können Sie Folgendes verwenden:

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

Dann, wenn die geschäftige Zeit beginnt, senden Sie es ein SIGSTOP:

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

Wenn der Server später wieder inaktiv ist, setzen Sie ihn fort.

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

Sie müssen dies für bestimmte Zeiten planen, wenn Sie möchten, dass es ausgeführt wird. Sie können Tools wie Cron- oder System-Timer (oder eine Vielzahl ähnlicher Tools) verwenden, um dies zu planen. Anstatt die Planung auf Basis eines Zeitintervalls vorzunehmen, können Sie den Server überwachen (z. B. anhand des Lastdurchschnitts, der CPU-Auslastung oder der Aktivität in den Serverprotokollen), um zu entscheiden, wann die Kopie angehalten oder fortgesetzt werden soll.

Sie müssen auch die PID-Datei verwalten (falls Sie eine verwenden), um sicherzustellen, dass Ihre Kopie tatsächlich noch ausgeführt wird, bevor Sie sie anhalten. Möglicherweise möchten Sie eine Bereinigung durchführen, indem Sie die PID-Datei entfernen, sobald die Kopie fertig ist usw.

Mit anderen Worten, Sie benötigen mehr Informationen, um eine zuverlässige Funktion zu gewährleisten. Die Grundidee, diese SIGSTOP- und SIGCONT-Signale zum Anhalten / Fortsetzen der Ausführung eines Prozesses zu verwenden, scheint jedoch genau das zu sein, wonach Sie suchen.

filbranden
quelle
1
Fügen Sie vielleicht eine Erinnerung hinzu, dass Sie sehr vorsichtig sein sollten, dass sich '/var/run/bigcopy.pid' immer noch auf denselben Prozess bezieht, wie Sie denken. Das zufällige Stoppen anderer Prozesse auf dem System ist möglicherweise nicht wünschenswert. Ich kenne keinen sicheren Weg, um sicherzustellen, dass die PID auf das Programm verweist, von dem Sie glauben, dass es dies tut ...
Evan Benn
@EvanBenn Ja, das habe ich so gemeint: "Vergewissere dich, dass deine Kopie noch läuft, bevor du sie pausierst." Ja, die Überprüfung von PIDs ist von Natur aus rennend, so dass es manchmal nicht wirklich möglich ist, dies zu 100% zuverlässig zu tun ...
22.
@cat Nicht wirklich, ein Prozess kann SIGSTOP nicht blockieren. Siehe den Link aus dem ersten Kommentar: "SIGSTOP ist ein nicht blockierbares Signal wie SIGKILL" (oder googeln Sie einfach, Sie werden sehen, dass dies der Fall ist.)
22.
76

Anstatt den Prozess anzuhalten, können Sie ihm auch eine niedrigere Priorität zuweisen:

renice 19 "$pid"

Gibt ihm die niedrigste Priorität (höchste Priorität), sodass dieser Prozess die CPU für andere Prozesse freigibt, die ihn die meiste Zeit benötigen.

Unter Linux kann dasselbe mit I / O gemacht werden mit ionice:

ionice -c idle -p "$pid"

Versetzt den Prozess in die "Leerlauf" -Klasse, sodass er nur dann Festplattenzeit erhält, wenn kein anderes Programm für eine definierte Nachfrist nach Festplatten-E / A gefragt hat .

Stéphane Chazelas
quelle
22
Dies ist ein typischer Fall eines XY-Problems . Die Frage war, wie man einen Prozess anhält, aber dies beantwortet die Frage nicht. Zwar ist die Herabsetzung der Priorität die bessere Lösung für das eigentliche Problem, sie beantwortet jedoch nicht die Frage. Ich würde die Frage bearbeiten , um auch anzugeben, wie ein Prozess angehalten werden soll und warum das Anhalten möglicherweise ein Problem darstellt (z. B. kann die Datei im angehaltenen Zustand bearbeitet werden).
MechMK1
22
@DavidStockinger, technisch gesehen gibt diese Antwort an, wie das Betriebssystem angewiesen wird, den Prozess anzuhalten, wenn es (das Betriebssystem, die CPU, der E / A-Scheduler) beschäftigt ist (auch wenn es sich jeweils um Sekundenbruchteile handelt). In anderen Antworten wurde bereits erläutert, wie Sie den Vorgang manuell unterbrechen können. Diese Lösung behebt nicht das Problem, dass Dateien während des Kopierens geändert werden.
Stéphane Chazelas
5
Das Ändern der E / A-Priorität ist nicht immer die beste Lösung. Wenn Sie von sich drehenden Datenträgern kopieren, kann es vorkommen, dass Sie vor jeder Anforderung mit hoher Priorität eine Suche durchführen, die Sie nicht ausführen würden, wenn Sie den Vorgang mit niedriger Priorität vollständig angehalten hätten.
Mark
2
Niedrigere Priorität löst das Problem nicht einmal. Selbst wenn die Box einige Sekunden oder Minuten lang völlig im Leerlauf ist, bedeutet dies nicht, dass ein umfangreicher Kopiervorgang, der alles aus dem Dateisystem-Cache entfernt, unauffällig wird. Sobald es wieder eine Ladung gibt, wird es sehr langsam sein, alles wieder einzulesen.
R ..
2
@DavidStockinger Die bevorzugte Art, mit XY-Problemen umzugehen, besteht darin, die richtige Lösung zu finden, auch wenn dies nicht die Frage ist, nach der die Frage gestellt wird. Wenn Sie wissen, dass der in der Frage beschriebene Ansatz falsch ist, gibt eine gute Antwort diesen falschen Ansatz nicht wieder, sondern schlägt einen besseren vor.
terdon
8

Verwenden Sie für dieses Szenario rsync und vergessen Sie cp. Es gibt Parameter, die die Bandbreite begrenzen oder die beendet und später gestartet werden können

Anton Tománek
quelle
3

Wenn Sie den laufenden Prozess unterbrechen, empfehle ich, mit dem Screen-Programm zu spielen. Ich habe Linux schon eine Weile nicht mehr verwendet, aber wenn Sie den Befehl in IIRC pausieren und später fortsetzen, sind Sie ziemlich verwundbar. Wenn Sie versehentlich abgemeldet werden, können Sie Ihre Sitzung nicht fortsetzen.

Ich glaube, Sie können die Sitzung mit screen unterbrechen, trennen und sich abmelden. Später können Sie wieder in diese Sitzung zurückkehren und sie erneut verbinden. Man müsste ein bisschen damit spielen, aber es hat die Sitzungen viel robuster gemacht.

Sie können sich auch abmelden und nach Hause gehen, sich dann per Fernzugriff anmelden, das System wieder anschließen, das Sie im Büro gestartet haben, und es für den Abend fortsetzen. Am nächsten Arbeitstag können Sie es dann wieder abholen.

Bill K
quelle
Ich benutze bereits tmux für das. Aber ich schreibe ein Skript, das sich selbst oder vorzugsweise der Umgebung bewusst ist, sodass es stoppt, wenn der Server überlastet ist, und fortgesetzt wird, wenn es normal ist.
Sollosa
0

Wenn Ihre Shell dies unterstützt (fast alle tun dies), können Sie ^ Z (Strg + Z) drücken, um auf einfache Weise ein SIGTSTPSignal an die Vordergrundaufgabe zu senden. Fahren Sie dann mit fg(im Vordergrund) oder bg(im Hintergrund) fort.

Wenn Sie dies für mehrere Aufgaben tun und später darauf zurückgreifen möchten, können Sie den jobsBefehl verwenden und dann mit zurückkehren fg/bg %#, wobei # die Zahl ist, die in Klammern für Aufträge angegeben ist.

Denken Sie daran, dass dies SIGTSTPetwas anders ist als SIGSTOP(was bei allen anderen Antworten verwendet wird), vor allem aufgrund der Tatsache, dass es ignoriert werden kann (aber ich habe kein Programm gesehen, das es außer ignoriert sl). Weitere Details zu dieser Antwort finden Sie auf StackOverflow .

Ave.
quelle
Überrascht, dass dies noch nicht beantwortet wurde.
Ave
Ty Ave, ich kenne diesen Multitasking-Trick. Aber damit das passiert, muss man auf dem Terminal sein, während ich ein Skript erstellen sollte, das die Arbeit von selbst erledigt, egal ob es Tage dauert oder nicht.
Sollosa
@Sollosa kann für andere mit der gleichen Frage und mit Zugriff auf ein Terminal nützlich sein.
Ave
Genau. Schön dich zu kennen Ave :)
Sollosa