🐡

プロセスグループとセッション関連の用語メモ

2024/11/01に公開

プロセスグループとセッションについては「ふつうのLinuxプログラミング」に書いてある文章が一番簡潔で分かりやすい。

https://blog.shibayu36.org/entry/2017/11/07/193000

  • プロセスグループとセッションの役割 277
    - プロセスグループはパイプでつながれたプロセス群全てにシグナルを送ることが出来るような仕組み
    - セッションはユーザーのログインからログアウトまでの流れを管理するための概念

プロセスグループ

プロセスグループはパイプでつながれたプロセス群に対してシグナルを送るための仕組み。

シェルは、一つのコマンドもしくはパイプラインの実行に使われるプロセス群に 対して一つのプロセスグループを生成する (例えば、コマンド "ls | wc" を実行するために生成される二つのプロセスは 同じプロセスグループに置かれる)

https://linuxjm.sourceforge.io/html/LDP_man-pages/man7/credentials.7.html

例えば以下のようなコマンドを実行すると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がセッションリーダーとなる。

また、lssortuniqを実行しているプロセスグループがフォアグラウンドプロセスグループになり、bashのプロセスグループとfindwcのプロセスグループがバックグランドプロセスグループになっている。

端末

端末とはGeneral Terminal Interfaceに従うキャラクターデバイスのこと。

A character special file that obeys the specifications of the general terminal interface.

https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/V1_chap03.html#tag_03_401

General Terminal Interfaceには、2つのmode(行単位で入力を処理するCanonical mode、viemacsなどのように1文字1文字処理するNon-canonical mode)の説明があったり、SIGINTが送られる特殊文字に関する仕様などが書いてある。

In canonical mode input processing, terminal input is processed in units of lines

https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/V1_chap11.html#tag_11_1_6

In non-canonical mode input processing, input bytes are not assembled into lines,

https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/basedefs/V1_chap11.html#tag_11_1_7

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

制御端末

新しくセッションが作られたときにセッションリーダーが一番最初にオープンした端末がそのセッションの制御端末になる。

あるセッションの全プロセスは一つの 制御端末 を共有する。 セッションリーダーが最初に端末をオープンした際に制御端末は設定される

https://linuxjm.sourceforge.io/html/LDP_man-pages/man7/credentials.7.html#:~:text=あるセッションの全プロセスは一つの 制御端末 を共有する

制御端末の読み込みを行えるのはセッションのフォアグラウンドプロセスグループのみで、セッションでフォアグラウンドになれるプロセスグループは1つまでになっている。

一つのセッションのジョブの中で、フォアグラウンドジョブになれるのは最大でも一つで、そのセッションの他のジョブはバックグラウンドジョブである。 フォアグラウンドジョブだけが端末からの読み込みを行える

https://linuxjm.sourceforge.io/html/LDP_man-pages/man7/credentials.7.html#:~:text=かなれない。-,一つのセッションのジョブの中で,-、フォアグラウンドジョ

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-CINTRになっているときに

->$ 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

上記の例ではlssortuniqのを実行しているプロセスグループに対して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.

https://pubs.opengroup.org/onlinepubs/9799919799/functions/_Exit.html

カーネル自体はバックグラウンドプロセスグループ'に対して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