はじめに
花粉がつらくなってきました... sts-250rrです。
開発エンジニアとして、チームにアサインされて1年が経とうとしています。(速い)
私が担当している商材は主にJavaで書かれているため、普段はJVM上で動くアプリケーションに意識が行ってしまいがちで、そもそもアプリケーションがどうやって動いているなど
(Tomcat上でアプリケーションを動かしているということは漠然と理解していますが...)
OSレベルまで掘り下げして理解できていないように感じています。
今回は基礎に振り返るという意味でLinuxのプロセスについてまとめていきます。 (本記事のコマンドはUnixOS系であるMacOSXで実行しています。)
プロセスって何?
プロセスとは、「OS上で実行中のプログラム」を指します。
プロセスが動いているということは、コンピュータリソース(CPUやメモリなど)を消費している状態です。
例えば、Linuxコマンドは1つのプログラムであるため、コマンド実行時にプロセスを1つ作成します。 この間、プロセスはCPUやメモリを消費してプログラムを実行しています。
プロセスの特徴には以下のようなものがあります。
- 1つのCPU上で同時に処理するプロセスは1つだけ
- 複数のプロセスが実行可能な場合、個々のプロセスを適当な長さの時間ごとにCPU上で順番に処理する。
psコマンドを叩いてみると複数のプロセスが動いているように見えます。
(ターミナルを2枚開いた状態で1枚目はPostgresに接続、2枚目でpsコマンドを実行 することで2つのプログラムが動いている状態を用意しています。)
$ ps -a PID TTY TIME CMD 17239 ttys001 0:00.02 login -pf sts 17240 ttys001 0:00.03 -bash 17642 ttys001 0:00.00 ps -a 15351 ttys017 0:00.03 login -pf sts 15352 ttys017 0:00.12 -bash 17237 ttys017 0:00.01 psql -U postgres -p 5432
PC上の操作でも複数の処理を同時に動かすことがあるように、
実際のWEBアプリケーションにおいても、ApatchとTomcat、データベースが同時に動いて1つのサービスとして機能しています。
これを実現しているものが次項のマルチプロセスになります。
マルチプロセス
マルチプロセスは複数のタスクを並行して実行する機能のことを指しますが、Linuxは厳密には同時並行で処理を行うことを実現してはいません。 Linuxがやっていることは人が認識できない時間でプロセスを区切り、順番に処理することで複数のプロセスが同時に処理をしているように振る舞っています。
プロセススケジューラ
複数のプロセスが同時に処理をしているように振る舞うようにするため、Linuxはプロセススケジューラという機能を持っています。 例えば3つのプロセスを同時に処理する場合、プロセススケジューラによって以下のようにプロセス0 → 1 → 2 と処理を行っていきます。
また、プロセスの処理は以下のように並列で進んでいきます。
プロセスを短い間隔(タイムスライス)に区切り、1つのCPU上で動くプロセスを切り替えることで複数のプロセスが同時に処理しているように振る舞っています。 タイムスライスはそれぞれ等しいくらいの長さで区切られ、プロセスが増えるとタイムスライスの数が増えるため1つのプロセスが完了するまでに時間がかかります。
コンテキストスイッチ
1つのCPU上で動くプロセスがタイムスライスで切り替わることをコンテキストスイッチと呼びます。
コンテキストスイッチは、タイムスライスの時間が切れると容赦なく発生します。
例として、プロセス1 → 2 と順に実行する1つのプログラムがあったとします。プログラムの実行中にプロセス1が起動した場合、プロセス1 → 3 → 2 という順序で実行される可能性があります。
1プログラム以外の要因(他のプロセスが間に起動したなど)によって完了時間が伸びる可能性があるという点がコンテキストスイッチによるプロセス特性の1つです。
プロセスの状態
ここまでで記載したように、1つのCPU上で動くプロセスは切り替わるため、プロセスは実行状態・スリープ状態などの複数の状態を持っています。 以下にプロセス状態の一例をあげます。
状態 | 意味 |
---|---|
実行状態 | CPU使用状態 |
実行待ち状態 | CPUが割り当てられるのを待っている |
スリープ状態 | イベントの発生を待っている(CPUは使っていない状態) |
ゾンビ状態 | 終了状態の受け取りを待っている |
プロセスの状態は以下のように遷移します。
プロセスはプロセススケジューラに基づき、CPUの実行権を得ると実行待ち状態から実行状態に遷移し、処理をすべて完了するまで、タイムスライス区切りで状態を遷移し続けます。 プロセスは終了状態を得ることで終了となります。
コマンドで確認
Mac上でtopコマンドを実行してみると以下のような出力になりました。(上部10件まで)
Processes: 418 total, 5 running, 413 sleeping, 1787 threads 19:16:35 Load Avg: 1.97, 3.00, 4.61 CPU usage: 7.7% user, 26.88% sys, 66.3% idle SharedLibs: 295M resident, 33M data, 29M linkedit. MemRegions: 109880 total, 3310M resident, 119M private, 1551M shared. PhysMem: 8606M used (2803M wired), 7777M unused. VM: 1959G vsize, 1882M framework vsize, 2689796(0) swapins, 2881396(0) swapouts. Networks: packets: 58205899/34G in, 48094735/17G out. Disks: 5133929/94G read, 2715156/54G written. PID COMMAND %CPU TIME #TH #WQ #PORT MEM PURG CMPRS PGRP PPID STATE BOOSTS %CPU_ME %CPU_OTHRS UID FAULTS COW MSGSENT MSGRECV SYSBSD SYSMACH CSW PAGEINS 3075 VBoxHeadless 59.5 01:52:54 39/2 5 996 908M 0B 47M 3075 3060 running *0[2] 0.00000 0.00000 501 272297 390 4904505+ 110938+ 80020677+ 12095394+ 56986420+ 760 0 kernel_task 28.9 01:47:26 172/4 0 0 105M 0B 0B 0 0 running 0[0] 0.00000 0.00000 0 173910+ 0 100809447+ 97799283+ 0 0 429621385+ 0 14655 firefox 15.0 04:38.25 61 4 775+ 443M+ 9384K 81M- 14655 1 sleeping *0[1192+] 0.00000 0.06446 501 1835132+ 15875 940954+ 304755+ 2763928+ 3000384+ 1945509+ 33761+ 15349 Terminal 6.4 00:11.47 9 4 261- 72M 33M+ 0B 15349 1 sleeping *0-[368+] 1.14998 0.42402 501 149598+ 491 55408+ 13334+ 134496+ 142201+ 63838+ 2824 2303 com.docker.h 5.6 02:01:48 15 0 38 2355M 0B 304M 2288 2300 sleeping *0[1] 0.00000 0.00000 501 725271 446 785 317 207705774+ 465 126169989+ 68 15698 top 4.3 00:01.43 1/1 0 25 5284K 0B 0B 15698 15352 running *0[1] 0.00000 0.00000 0 11303+ 109 489446+ 244672+ 39445+ 314731+ 1968+ 0 226 WindowServer 3.1 15:54.83 10 5 1377- 447M 19M 47M 226 1 sleeping *0[1] 0.38155 0.00856 88 1809748+ 8936 13705840+ 6222509+ 5598080+ 19197483+ 7974577+ 9094 188 hidd 1.9 02:39.48 5 3 241 3492K 0B 664K 188 1 sleeping *0[1] 0.00688 0.00000 261 83167+ 171 629366+ 489469+ 5409421+ 1849976+ 2190289+ 5218 265 airportd 1.1 03:49.45 12 10 1385+ 13M+ 0B 5144K- 265 1 sleeping *14180[212] 0.00000 0.93819 0 243908+ 268 5776050+ 2282663+ 11177993+ 5077848+ 4985570+ 2748 171 locationd 0.6 01:34.95 7 5 231+ 8600K+ 192K 1420K 171 1 sleeping 0[22641] 1.15398 0.00000 205 207357+ 338 357612+ 97377+ 3218875+ 737171+ 876386+ 12727
まだまだ情報量が多く見づらいので、Terminalとtopコマンドだけ抜粋します。
PID COMMAND %CPU TIME #TH #WQ #PORT MEM PURG CMPRS PGRP PPID STATE BOOSTS %CPU_ME %CPU_OTHRS UID FAULTS COW MSGSENT MSGRECV SYSBSD SYSMACH CSW PAGEINS 15349 Terminal 6.4 00:11.47 9 4 261- 72M 33M+ 0B 15349 1 sleeping *0-[368+] 1.14998 0.42402 501 149598+ 491 55408+ 13334+ 134496+ 142201+ 63838+ 2824 15698 top 4.3 00:01.43 1/1 0 25 5284K 0B 0B 15698 15352 running *0[1] 0.00000 0.00000 0 11303+ 109 489446+ 244672+ 39445+ 314731+ 1968+ 0
topコマンドは今正しく動いているプログラムであるため状態は実行中(running)となっています。
対して、Terminalはtopコマンドの実行後、入力待ち状態となったためスリープ状態(sleeping)となっています。
手元で実行していただくとわかるかと思いますが、topコマンド実行中にコマンドを終了させてみたり、新しく実行してみたりすると
プロセスの生成や状態がみるみる変わっていく様子を見ることができます。
ゾンビプロセス
IDEなどで開発をしている中で、「既に8080ポートが使われている」などの理由でアプリ起動に失敗した経験が皆さんにもあるのではないでしょうか?
そんな悪さをしているのがゾンビプロセスです。
ゾンビプロセスが生まれてしまう原因は様々ですが、
一定時間子プロセスからの返答がなかったことから、タイムアウトとして親プロセスを終了してしまい子プロセスが宙に浮いてしまう。
というものがよくある1つの例かと思います。
「親プロセスが終了したからといって子プロセスもあわせて勝手に終了するわけではない」と覚えておきましょう。(その逆もしかりです。)
ゾンビプロセスができてしまったときは対象のプロセスを調べ、Killして対処しましょう。
まとめ
雑多になりましたが、Linuxのプロセスについてまとめていきました。 書籍やブログ記事などで知識を得ることはできますが、なにぶんOSの裏の動きは実際に手を動かしてみないとピンとこないものです。 コマンドは知っていても見方や期待される状態は知識のみでは補えない点も多いかと思います。 コーディングに疲れて一息つくときなどにpsコマンドやtopコマンドをボーっと眺めて、変化が起きる瞬間をウォッチしてみると面白い発見や知識がつながる瞬間があるかもしれません。
また、Linuxコマンドの一覧表を以下ブログにてまとめておりますので、ご参考ください。
よく使うLinuxコマンド一覧【最新版】
Linuxの理解をより深めたい方へ以下関連おすすめブログ
・ls コマンド 【使い方 まとめ】
・find コマンド 【使い方 まとめ】
・iptables まとめ【Linux ファイアウォール】
・sed コマンド【使い方 まとめ】
・ vi コマンド【使い方まとめ】
・ Linuxのファイル操作でよく使うLinuxコマンド
・ 初心者のためのawkコマンド
・ 実務で使える!基本的なシェル(Linux)コマンドの話 ~forとsed~
参考資料
エンジニア中途採用サイト
ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
ご興味ありましたら是非ご確認をお願いします。
https://career-recruit.rakus.co.jp/career_engineer/カジュアル面談お申込みフォーム
どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
以下フォームよりお申込みください。
rakus.hubspotpagebuilder.comラクスDevelopers登録フォーム
https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/イベント情報
会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!
◆TECH PLAY
techplay.jp
◆connpass
rakus.connpass.com