C'è un modo per mettere in pausa un processo in esecuzione su sistemi Linux e riprenderlo in seguito?


38

Devo copiare i file su una macchina. E i dati sono immensamente grandi. Ora i server devono servire normalmente, e di solito c'è un intervallo particolare di ore di punta su quelli. Quindi c'è un modo per eseguire tali comandi in modo tale che se il server raggiunge le ore di punta, mette in pausa il processo e quando esce da tale intervallo, lo riprende?

Destinato-Risultato

cp src dst

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

22
rsync può riprendere i trasferimenti parziali
Thorbjørn Ravn Andersen il

2
Hai bisogno di copiare i dati effettivi come backup? In caso contrario, potresti utilizzare cp -alper creare una fattoria con collegamento fisico? O utilizzare un filesystem che supporti i reflink a livello di blocco con copia su scrittura, usando cp -a --reflink=auto? BTRFS e ZFS supportano questo per le copie all'interno dello stesso dispositivo fisico.
Peter Cordes,

9
Qualcuno dei file srccambia tra le 9:00 e le 14:00? In tal caso, semplicemente sospendere e riprendere il cpprocesso può causare file danneggiati. Potrebbe essere meglio eseguire rsyncin combinazione con il timeoutcomando.
Mark Plotnick, il

Da e verso dove vengono copiati i file? È un sistema virtuale? Qual è il filesystem di origine? Qual è lo scopo della copia?
Braiam,

@Braiam Im usando rsync e copiando i file dal computer remoto al computer locale. Ho appena usato il comando cp come esempio qui a proposito
Sollosa il

Risposte:


8

Sì, è necessario

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

Il processo verrà quindi visualizzato con lo stato "T" (PS). Per continuare, fai un

$> kill -CONT <pid>

In bocca al lupo!


77

È possibile mettere in pausa l'esecuzione di un processo inviandogli un segnale SIGSTOP e successivamente riprenderlo inviandolo un SIGCONT.

Supponendo che il carico di lavoro sia un singolo processo (non fork di helper in esecuzione in background), è possibile utilizzare qualcosa del genere:

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

Quindi quando inizia il tempo occupato, inviagli un SIGSTOP:

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

Più tardi, quando il server è di nuovo inattivo, riprenderlo.

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

Dovrai pianificare questo per momenti specifici quando lo desideri, puoi usare strumenti come cron o systemd timer (o una varietà di altri strumenti simili) per ottenere questo programmato. Invece di pianificare in base a un intervallo di tempo, è possibile scegliere di monitorare il server (magari osservando la media del carico, l'utilizzo della CPU o l'attività dai registri del server) per decidere quando mettere in pausa / riprendere la copia.

Devi anche gestire il file PID (se ne usi uno), assicurati che la tua copia sia effettivamente in esecuzione prima di metterlo in pausa, probabilmente vorrai ripulirlo rimuovendo il file pid al termine della copia, ecc.

In altre parole, hai bisogno di altro per renderlo affidabile, ma l'idea di base di utilizzare questi segnali SIGSTOP e SIGCONT per mettere in pausa / riprendere l'esecuzione di un processo sembra essere ciò che stai cercando.



1
Forse aggiungi un promemoria che dovresti fare molta attenzione che '/var/run/bigcopy.pid' faccia ancora riferimento allo stesso processo che pensi che faccia. l'interruzione casuale di altri processi sul sistema potrebbe non essere auspicabile. Non conosco un modo sicuro per garantire che il pid si riferisca al programma che pensi che faccia comunque ...
Evan Benn,

@EvanBenn Sì, questo è quello che intendevo in un certo senso con "assicurati che la tua copia sia effettivamente ancora in esecuzione prima di metterla in pausa" anche se il tuo punto è sicuramente più esplicito di così! Sì, il controllo dei PID è intrinsecamente da corsa, quindi a volte non è davvero possibile farlo in modo affidabile al 100% ...
filbranden,

@cat Non proprio, un processo non può bloccare SIGSTOP. Vedi il link dal primo commento: "SIGSTOP è un segnale non bloccabile come SIGKILL" (o semplicemente google, vedrai che è così).
filbranden,

76

Invece di sospendere il processo, potresti anche dargli una priorità più bassa:

renice 19 "$pid"

gli darà la priorità più bassa (massima gentilezza), in modo tale processo renderà la CPU ad altri processi che ne hanno bisogno per la maggior parte del tempo.

Su Linux, lo stesso può essere fatto con l'I / O con ionice:

ionice -c idle -p "$pid"

Inserirà il processo nella classe "inattiva", in modo tale da ottenere il tempo su disco solo quando nessun altro programma ha richiesto l'I / O del disco per un periodo di tolleranza definito .


22
Questo è un tipico caso di un problema XY . La domanda era come mettere in pausa un processo, ma questo non risponde alla domanda. Mentre in effetti abbassare la priorità è l'approccio migliore al problema reale , non risponde alla domanda. Vorrei modificare la domanda per includere anche il modo di mettere in pausa un processo e perché la pausa potrebbe essere un problema (ad esempio, il file potrebbe essere modificato durante la pausa).
MechMK1

22
@DavidStockinger, tecnicamente, questa risposta spiega come dire al sistema operativo di mettere in pausa il processo quando (il sistema operativo, la CPU, lo scheduler I / O) è occupato (anche se è per frazioni di secondi alla volta). Come sospendere il processo manualmente è già stato trattato in altre risposte. Questa soluzione non risolve il problema della modifica dei file durante la loro copia.
Stéphane Chazelas,

5
La modifica della priorità I / O non è sempre la soluzione migliore. Se stai copiando da dischi rotanti, potresti comunque incorrere in una ricerca prima di ogni richiesta ad alta priorità che non dovresti sostenere se sospendi completamente l'operazione a bassa priorità.
Segna il

2
Una priorità più bassa non risolve nemmeno il problema. Anche se la scatola è completamente inattiva per alcuni secondi o minuti, ciò non significa che un enorme processo di copia che eliminerà tutto dalla cache del filesystem non sarà invadente. Non appena ci sarà di nuovo un carico, sarà molto lento effettuare il paging di tutto.
R ..

2
@DavidStockinger il modo preferito di affrontare i problemi XY è quello di dare la soluzione giusta , anche se non è questo il problema. Quando sai che l'approccio descritto nella domanda è sbagliato, una buona risposta non dà quell'approccio sbagliato ma invece ne propone uno migliore.
terdon

8

Usa rsync, dimentica di cp, per questo scenario. ci sono parametri per limitare la larghezza di banda, o possono essere uccisi / fermati e avviati in seguito, in un modo in cui continuerà, dove ha lasciato google rsync esempio / i


3

Se hai intenzione di farlo interrompendo il processo in esecuzione, ti suggerisco di giocare con il programma Screen. Non uso Linux da un po 'di tempo, ma IIRC semplicemente mettendo in pausa il comando e riprendendolo in seguito ti rende piuttosto vulnerabile, se ti disconnetti accidentalmente non sarai in grado di riprendere la sessione.

Con lo schermo credo che tu possa interrompere la sessione, quindi staccarla e disconnettersi. Successivamente puoi tornare indietro e ricollegarti a quella sessione. Dovresti giocarci un po 'ma ha reso le sessioni molto più robuste.

Puoi anche disconnetterti e tornare a casa, quindi accedere in remoto, ricollegarti al sistema y hai iniziato in ufficio e riprenderlo per la sera, quindi riprenderlo il giorno successivo al lavoro.


Sto già usando tmux per quello. Ma sto scrivendo uno script che sarebbe autocosciente o preferibilmente consapevole dell'ambiente, quindi si interrompe se il server ottiene traffico elevato e continua quando è normale.
Sollosa,

0

Se la tua shell lo supporta (quasi tutti lo fanno), puoi premere ^ Z (Ctrl + Z) per inviare facilmente un SIGTSTPsegnale all'attività in primo piano, quindi continuare con fg(in primo piano) o bg(sullo sfondo).

Se si esegue questa operazione su più attività e si desidera tornare a esse in un secondo momento, è possibile utilizzare il jobscomando, quindi tornare con fg/bg %#, dove # è il numero indicato tra parentesi sui lavori.

Tieni presente che SIGTSTPè un po 'diverso da SIGSTOP(che viene utilizzato su tutte le altre risposte), soprattutto a causa del fatto che può essere ignorato (ma non ho visto un programma ignorarlo a parte sl). Maggiori dettagli sono disponibili su questa risposta su StackOverflow .


Sorpreso che nessuna risposta lo abbia menzionato ancora.
Ave,

Ty Ave, conosco questo trucco multitasking. Ma perché ciò accada, è necessario essere sul terminale, mentre dovevo costruire uno script che farà il lavoro da solo, non importa se ci vorranno giorni.
Sollosa,

@Sollosa può essere utile ad altri con la stessa domanda e con accesso a un terminale.
Ave,

Sono d'accordo. Bello conoscerti Ave :)
Sollosa,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.