11

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?

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

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

4

(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
  • Interesting. Are you able to provide any examples, please? – roaima Mar 18 '16 at 22:40
  • > 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 Mar 18 '16 at 23:23
0

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.