问题描述
如果我正在运行一个长时间运行的进程,当我使用 + 停止它时,我会在终端中收到以下消息:
If I am running a long-running process, and when I stop it with +, I get the following message in my terminal:
76381 suspended git clone [email protected]:kevinburke/<large-repo>.git
当进程暂停时实际发生了什么?状态是否保存在内存中?此功能是否在操作系统级别实现?当我用 fg
重新启动它时,该进程如何能够从它停止的地方恢复执行?
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
?
推荐答案
当您在终端中按 + 时,(伪-)终端设备驱动程序(内核)向终端设备前台进程组中的所有进程发送一个SIGTSTP
信号.
When you hit + 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.
那个进程组是终端设备的一个属性.通常,您的 shell 是定义哪个进程组是终端设备的前台进程组的进程.
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.
在shell术语中,进程组被称为作业",您可以使用fg
和bg
命令将作业放在前台和后台并找出使用 jobs
命令了解当前正在运行的作业.
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.
SIGTSTP
信号类似于 SIGSTOP
信号,除了与 SIGSTOP
相反,SIGTSTP
可以通过一个过程.
The SIGTSTP
signal is like the SIGSTOP
signal except that contrary to SIGSTOP
, SIGTSTP
can be handled by a process.
在接收到这样的信号后,进程被暂停.也就是说,它被暂停并仍然在那里,只是它不会被调度运行,直到它被杀死或发送 SIGCONT
信号以恢复执行.启动作业的 shell 将等待其中的进程组的领导者.如果它被挂起,wait()
将返回指示进程被挂起.然后,shell 可以更新作业的状态并告诉您它已暂停.
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
这篇关于在进程上按 ctrl+z 会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!