Unterbrechen Sie den Vorgang, ohne ihn zu beenden

11

Ich habe also ein beständiges Programm im Hintergrund. Wenn Sie es beenden, wird es nur mit einer anderen PID neu gestartet. Ich möchte es aussetzen (einschläfern lassen, ohne es tatsächlich zu töten). Tut kill -9 das? Wenn nicht, wie soll das gemacht werden?

kovach.j
quelle

Antworten:

14
kill -STOP $PID
[...]
kill -CONT $PID

@jordanm fügt hinzu: Beachten Sie auch, dass kill -9SIGSTOP wie SIGKILL ( ) nicht ignoriert werden kann.

Hauke ​​Laging
quelle
4

(Auch zur Beantwortung doppelter / geschlossener Fragen Wie kann ich einen laufenden Prozess anhalten oder einfrieren? Ich frage , was zu tun ist, wenn Anwendungen nach dem Fortsetzen abstürzen.)

Es gibt Prozesse, die nach kill -STOP $PID& nicht ordnungsgemäß fortgesetzt werden kill -CONT $PID. In diesem Fall können Sie Checkpoint / Restore mit CRIU versuchen . Wenn Ihnen der Overhead nichts ausmacht, können Sie den Prozess auch in einer virtuellen Maschine ausführen, die Sie anhalten können.

Ein Grund, warum ein Prozess nach SIGSTOP / SIGCONT nicht fortgesetzt wird, kann sein, dass einige blockierende Systemaufrufe unter Linux mit EINTR fehlschlagen, wenn der Prozess gestoppt und dann über SIGCONT fortgesetzt wird. Vom Signal (7) :

Unterbrechung von Systemaufrufen und Bibliotheksfunktionen durch Stoppsignale

Unter Linux können auch ohne Signalhandler bestimmte blockierende Schnittstellen mit dem Fehler EINTR ausfallen, nachdem der Prozess durch eines der Stoppsignale gestoppt und dann über SIGCONT fortgesetzt wurde. Dieses Verhalten wird von POSIX.1 nicht genehmigt und tritt auf anderen Systemen nicht auf.

[...]

Einer der betroffenen Systemaufrufe ist epoll_wait (2) . Beispiel:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <sys/epoll.h>

int
main(int argc, char *argv[])
{
    int fd = 0;

    int efd = epoll_create(1);
    if (efd == -1) {
        perror("epoll_create");
        exit(1);
    }

    struct epoll_event ev;
    memset(&ev, 0, sizeof(ev));
    ev.events = EPOLLIN;
    ev.data.fd = fd;

    if (epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ev) == -1) {
        perror("epoll_ctl");
        exit(1);
    }

    int res = epoll_wait(efd, &ev, 1, -1);
    if (res == -1) {
        perror("epoll_wait");
        exit(1);
    }

    if (ev.events & EPOLLIN && ev.data.fd == fd) {
        printf("Received input\n");
    }

    return 0;
}

Kompilieren und ausführen:

$ gcc -o example example.c
$ echo 'input' | ./example
Received input
$ ./example
Ctrl+Z
[1]+  Stopped                 ./example
$ fg
./example
epoll_wait: Interrupted system call
Peter
quelle
Interessant. Können Sie bitte Beispiele nennen?
Roaima
> und dann über SIGCONT fortgesetzt <es heißt, dass der Systemaufruf EINTRbeim SIGCONTSenden an den gestoppten Prozess eingeht . Das Programm bleibt gestoppt, bis SIGCONTes gesendet wird
myaut
0

Sie können pkill verwenden , um die STOPund CONT-Signale an Prozessnamen zu senden , sodass Sie die PID nicht herausfinden müssen.

So unterbrechen Sie einen Prozess nach Namen:

 pkill --signal STOP ProcessNameToSuspend

Um diesen Prozess wieder zu aktivieren:

 pkill --signal CONT ProcessNameToSuspend
Alex Stragies
quelle