14

So I've got a persistent program running in the background. Killing it just causes it to restart with a different PID. I'd like to suspend it (put it to sleep without actually killing it). Does kill -9 do this? If not, how should this be done?

3 Answers 3

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

@jordanm adds: Also note that like SIGKILL (same as kill -9) and SIGSTOP can not be ignored.

0
6

(Also to answer duplicate/closed question How can I pause or freeze a running process?, asking about what to do when applications crash after resume.)

There are processes which do not resume properly after kill -STOP $PID & kill -CONT $PID. If that is the case you can try checkpoint/restore with CRIU. If you do not mind the overhead you can also run the process in a virtual machine, which you can suspend.

One reason why a process does not resume after SIGSTOP/SIGCONT could be that some blocking system calls on Linux fail with EINTR when the process is stopped and then resumed via SIGCONT. From signal(7):

Interruption of system calls and library functions by stop signals

On Linux, even in the absence of signal handlers, certain blocking interfaces can fail with the error EINTR after the process is stopped by one of the stop signals and then resumed via SIGCONT. This behavior is not sanctioned by POSIX.1, and doesn't occur on other systems.

[...]

One of the affected system calls is epoll_wait(2). Example:

#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;
}

Compile and run:

$ gcc -o example example.c
$ echo 'input' | ./example
Received input
$ ./example
Ctrl+Z
[1]+  Stopped                 ./example
$ fg
./example
epoll_wait: Interrupted system call
1
  • > and then resumed via SIGCONT < it says that system call gets EINTR when SIGCONT sent to stopped process. The program remains stopped until SIGCONT is sent
    – myaut
    Commented Mar 18, 2016 at 23:23
2

You can use pkill to send the STOP and CONT signals to process-names, so that you don't need to find out the PID.

To suspend a process by name:

 pkill --signal STOP ProcessNameToSuspend

To wake that process back up:

 pkill --signal CONT ProcessNameToSuspend

On standard systems you have TAB-completion for the ProcessName, as well as for all other command elements.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .