プロセスグループとセッション関連の用語メモ
プロセスグループとセッションについては「ふつうのLinuxプログラミング」に書いてある文章が一番簡潔で分かりやすい。
- プロセスグループとセッションの役割 277
- プロセスグループはパイプでつながれたプロセス群全てにシグナルを送ることが出来るような仕組み
- セッションはユーザーのログインからログアウトまでの流れを管理するための概念
プロセスグループ
プロセスグループはパイプでつながれたプロセス群に対してシグナルを送るための仕組み。
シェルは、一つのコマンドもしくはパイプラインの実行に使われるプロセス群に 対して一つのプロセスグループを生成する (例えば、コマンド "ls | wc" を実行するために生成される二つのプロセスは 同じプロセスグループに置かれる)
例えば以下のようなコマンドを実行するとps
と2つのcat
は異なるプロセスIDを持っているが、同じプロセスグループに属していることが分かる。
ps -o pid,ppid,pgid,sid,comm | cat | cat
PID PPID PGID SID COMMAND
310064 310053 310064 310064 zsh
562468 310064 562468 310064 ps
562469 310064 562468 310064 cat
562470 310064 562468 310064 cat
セッション、セッションリーダー
セッションはユーザーがログインしてからログアウトするまでの流れを管理するための概念。例えば、ターミナルで以下のようなコマンドを実行し最後のls / | sort | uniq -c
が実行中のとき、各プロセスの関係は以下のようになっている。
$ find / 2>/dev/null | wc -l &
[1] 52291 52292
$ ls / | sort | uniq -c
実行中
plantuml
@startuml
!theme blueprint
scale 1024 width
card session {
card "process group 1\n(Background)\n(Session Leader)" {
rectangle bash
}
card "process group 2\n(Background)" {
rectangle find
rectangle wc
}
card "process group 3\n(Foreground)" {
rectangle ls
rectangle sort
rectangle uniq
}
}
@enduml
bash
から実行された各コマンドのプロセスグループは同じセッションに属していて、このセッションを作ったプロセスであるbash
がセッションリーダーとなる。
また、ls
とsort
、uniq
を実行しているプロセスグループがフォアグラウンドプロセスグループになり、bash
のプロセスグループとfind
、wc
のプロセスグループがバックグランドプロセスグループになっている。
端末
端末とはGeneral Terminal Interfaceに従うキャラクターデバイスのこと。
A character special file that obeys the specifications of the general terminal interface.
General Terminal Interfaceには、2つのmode(行単位で入力を処理するCanonical mode、vi
やemacs
などのように1文字1文字処理するNon-canonical mode)の説明があったり、SIGINT
が送られる特殊文字に関する仕様などが書いてある。
In canonical mode input processing, terminal input is processed in units of lines
In non-canonical mode input processing, input bytes are not assembled into lines,
INTR
Special character on input, which is recognized if the ISIG flag is set. Generates a SIGINT signal which is sent to all processes in the foreground process group for which the terminal is the controlling terminal. If ISIG is set, the INTR character shall be discarded when processed.
制御端末
新しくセッションが作られたときにセッションリーダーが一番最初にオープンした端末がそのセッションの制御端末になる。
あるセッションの全プロセスは一つの 制御端末 を共有する。 セッションリーダーが最初に端末をオープンした際に制御端末は設定される
制御端末の読み込みを行えるのはセッションのフォアグラウンドプロセスグループのみで、セッションでフォアグラウンドになれるプロセスグループは1つまでになっている。
一つのセッションのジョブの中で、フォアグラウンドジョブになれるのは最大でも一つで、そのセッションの他のジョブはバックグラウンドジョブである。 フォアグラウンドジョブだけが端末からの読み込みを行える
plantuml
@startuml
!theme blueprint
scale 1024 width
card session {
card "process group 1\n(Background)\n(Session Leader)" {
rectangle bash
}
card "process group 2\n(Background)" {
rectangle find
rectangle wc
}
card "process group 3\n(Foreground)" as pg3 {
rectangle ls
rectangle sort
rectangle uniq
}
}
rectangle "制御端末" as controlling_terminal
bash --> controlling_terminal: "open"
controlling_terminal <-- pg3: "can read input"
@enduml
Ctrl-C
(INTR
)を押したとき
Ctrl-C
がINTR
になっているときに
->$ stty -a
speed 38400 baud; rows 115; columns 207; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc
Ctrl-C
を押すとそのセッションのフォアグラウンドプロセスグループにSIGINT
が送られる
INTR
Special character on input, which is recognized if the ISIG flag is set. Generates a SIGINT signal which is sent to all processes in the foreground process group for which the terminal is the controlling terminal. If ISIG is set, the INTR character shall be discarded when processed.
https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/V1_chap11.html#tag_11_1_9
上記の例ではls
とsort
、uniq
のを実行しているプロセスグループに対してSIGINT
が送られる。
plantuml
@startuml
!theme blueprint
scale 1024 width
card session {
card "process group 1\n(Background)\n(Session Leader)" as pg1 {
rectangle bash
}
card "process group 2\n(Background)" {
rectangle find
rectangle wc
}
card "process group 3\n(Foreground)" as pg3 #line.dotted{
rectangle ls #line.dotted
rectangle sort #line.dotted
rectangle uniq #line.dotted
}
}
card "カーネル" as kernel {
rectangle "制御端末" as controlling_terminal
}
circle user as " "
user --> kernel: "Ctrl-C"
kernel -d-> pg3: "SIGHUP"
@enduml
セッションリーダーが終了したとき
セッションリーダーが終了したとき、そのセッションのフォアグラウンドプロセスグループに対してSIGHUP
が送られる。
If the process is a controlling process, the SIGHUP signal shall be sent to each process in the foreground process group of the controlling terminal belonging to the calling process.
カーネル自体はバックグラウンドプロセスグループ'に対してSIGHUP
は送らない。そのため、bash
からバックグラウンド実行したプロセスグループは起動したまま残る(huponexit
が有効になっていない場合)。
plantuml
@startuml
!theme blueprint
scale 1024 width
card session {
card "process group 1\n(Foreground)\n(Session Leader)" as pg1 #line.dotted {
rectangle bash #line.dotted
}
card "process group 2\n(Background)" {
}
card "process group 3\n(Background)" {
}
}
actor user
user --> bash: exit
@enduml
Discussion