今回はこちらの書籍「[試して理解]Linuxのしくみ〜実験と図解で学ぶOSとハードウェアの基礎知識」 の3章 プロセス管理について、自己理解のために内容をかいつまんで要約します。素晴らしい書籍で理解が進むと思いますのでぜひご購入を検討ください。
プロセスとは
Linuxでは稼働するアプリケーションをプロセスという単位で管理しています。このプロセスですが2種類の生成する目的があります。
- マルチプロセス(同じ処理を複数のプロセスで実行する並列化)
- 異なるプログラムを生成する
そのため目的ごとにfork()
とexecve()
と呼ばれる2種類のプロセスを生成するシステムコールが用意されています。
fork()関数
fork()
は「マルチプロセス(同じ処理を複数のプロセスで実行する並列化)」のために用いられます。基本的な動作は以下の通りです。
- 子プロセス用のメモリ領域を作成し、親プロセスのメモリをコピー
- 親プロセスとこプロセスは違うコードを実行するように分岐
bashコマンドにおけるpipe(|)はpipeでつないだ時にfork()
を使って子プロセスを起動します。
$ sleep 3000 | sleep 1000 | sleep 2000 7574 pts/1 S 0:00 \_ /bin/bash 10179 pts/1 S+ 0:00 \_ sleep 3000 10180 pts/1 S+ 0:00 \_ sleep 1000 10181 pts/1 S+ 0:00 \_ sleep 2000
このようにbashプロセスの下に3つの子プロセスが存在します。
execve()関数
execve()
は現在のプロセスのメモリを新しいプロセスのデータで上書きを行います。そのためSSHをしている環境において以下のコマンドを実行すると1秒後に端末がクローズします。(シェルではexecコマンド
を通じて利用が可能です)
$ exec sleep 1
これは現在開いているシェル(bashとする)プロセスがexec
によってsleepプロセスに変換され、sleepが1秒後に正常終了されたからです。正常終了されるとSSHのコネクションも切断され端末も終了します。
sleepを10000に増やしてexec
してみるとこのようになっています。本来はssh→bash→sudo -s→bash→sleep 10000
となるはずですが、最後のbashがexec
によってsleep 10000
プロセスに上書きされたため存在していません。
[root@master vagrant]# exec sleep 10000 [root@master vagrant]# ps axf 〜 7534 ? Ss 0:00 \_ sshd: vagrant [priv] 7537 ? S 0:00 \_ sshd: vagrant@pts/1 7538 pts/1 Ss 0:00 \_ -bash 7572 pts/1 S+ 0:00 \_ sudo -s 7574 pts/1 S+ 0:00 \_ sleep 10000 〜
fork()
だとこの通り/bin/bashが存在していますね。
7534 ? Ss 0:00 \_ sshd: vagrant [priv] 7537 ? S 0:00 \_ sshd: vagrant@pts/1 7538 pts/1 Ss 0:00 \_ -bash 10702 pts/1 S 0:00 \_ sudo -s 10705 pts/1 S 0:00 \_ /bin/bash 10747 pts/1 S+ 0:00 \_ sleep 10000
まとめ
この章ではfork()
とexecve()
を利用したプロセス生成について整理しました。書籍にはより詳しい情報や、基礎的なため今回は端折った内容も豊富に掲載されていますので勉強の際はぜひお買い求めください。