If I am running a long-running process, and when I stop it with Ctrl+Z, I get the following message in my terminal:
76381 suspended git clone [email protected]:kevinburke/<large-repo>.git
What actually happens when the process is suspended? Is the state held in memory? Is this functionality implemented at the operating system level? How is the process able to resume execution right where it left off when I restart it with fg
?
When you hit Ctrl+Z in a terminal, the line-discipline of the (pseudo-)terminal device driver (the kernel) sends a SIGTSTP
signal to all the processes in the foreground process group of the terminal device.
That process group is an attribute of the terminal device. Typically, your shell is the process that defines which process group is the foreground process group of the terminal device.
In shell terminology, a process group is called a "job", and you can put a job in foreground and background with the fg
and bg
command and find out about the currently running jobs with the jobs
command.
The SIGTSTP
signal is like the SIGSTOP
signal except that contrary to SIGSTOP
, SIGTSTP
can be handled by a process.
Upon reception of such a signal, the process is suspended. That is, it's paused and still there, only it won't be scheduled for running any more until it's killed or sent a SIGCONT
signal to resume execution. The shell that started the job will be waiting for the leader of the process group in it. If it is suspended, the wait()
will return indicating that the process was suspended. The shell can then update the state of the job and tell you it is suspended.
$ sleep 100 | sleep 200 & # start job in background: two sleep processes
[1] 18657 18658
$ ps -lj # note the PGID
F S UID PID PPID PGID SID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 10031 18657 26500 18657 26500 0 85 5 - 2256 - pts/2 00:00:00 sleep
0 S 10031 18658 26500 18657 26500 0 85 5 - 2256 - pts/2 00:00:00 sleep
0 R 10031 18692 26500 18692 26500 0 80 0 - 2964 - pts/2 00:00:00 ps
0 S 10031 26500 26498 26500 26500 0 80 0 - 10775 - pts/2 00:00:01 zsh
$ jobs -p
[1] + 18657 running sleep 100 |
running sleep 200
$ fg
[1] + running sleep 100 | sleep 200
^Z
zsh: suspended sleep 100 | sleep 200
$ jobs -p
[1] + 18657 suspended sleep 100 |
suspended sleep 200
$ ps -lj # note the "T" under the S column
F S UID PID PPID PGID SID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 T 10031 18657 26500 18657 26500 0 85 5 - 2256 - pts/2 00:00:00 sleep
0 T 10031 18658 26500 18657 26500 0 85 5 - 2256 - pts/2 00:00:00 sleep
0 R 10031 18766 26500 18766 26500 0 80 0 - 2964 - pts/2 00:00:00 ps
0 S 10031 26500 26498 26500 26500 0 80 0 - 10775 - pts/2 00:00:01 zsh
$ bg %1
[1] + continued sleep 100 | sleep 200
$ ps -lj
F S UID PID PPID PGID SID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 10031 18657 26500 18657 26500 0 85 5 - 2256 - pts/2 00:00:00 sleep
0 S 10031 18658 26500 18657 26500 0 85 5 - 2256 - pts/2 00:00:00 sleep
0 R 10031 18824 26500 18824 26500 0 80 0 - 2964 - pts/2 00:00:00 ps
0 S 10031 26500 26498 26500 26500 0 80 0 - 10775 - pts/2 00:00:01 zsh
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With