マルチユーザ・マルチタスクのシステムではプロセス管理が非常に重要
- プログラム単位ではなくプロセス単位で実行が管理される/プロセスIDの使用
- 同時に同じプログラムを2種類動作させてもお互いが干渉しない
- Linuxではメモリー領域を仮想メモリー空間を割り当てる方式で干渉を防止している
プロセスの生成から終了までの流れは以下の通り。
- プロセスがfork()システム・コールを発行して自分自身を新しいプログラムに置き換える(複製)
- 複製されたプロセスはexec()システム・コールを発行して自分自身を新しいプログラムに置き換える(処理)
- 処理完了後にexit()システム・コールにより自分自身を終了させる
※親プロセスは子プロセスが終了するのを待機する
各項目の詳細は以下の通り。
fork()システム・コール
exec()システム・コール
- 自分自身を新しいプログラムに置き換えて実行するシステム・コール
- 仮想メモリー空間を一度開放し、新たに作成してそこに指定したプログラムを割り当てて実行する
※メモリー空間以外の全ての情報はそのまま引き継ぐ
※全てのプロセスは親子関係を持つ。ただし、全てのプロセスの根幹になっているinitプロセス(プロセスID:1)だけはKernelが自身で生成する。全てのプロセスはinitを基幹とするツリー構造で構成される。
exit()システム・コール
- カーネルにより対象プロセスが使用していた資源を解放する
※プロセス自体の管理情報は親プロセスによって削除される
wait()システム・コール
- 子プロセスが終了された時点で子プロセスの管理情報を削除するシステム・コール
- 発行のタイミングは子プロセスをfork()してすぐでも終了シグナルを受け取った時点でもかまわない
※親プロセスによってwait()が発行されていない終了プロセスを"defunctプロセス"もしくは"ゾンビプロセス"と呼ぶ
※wait()は必ずしも直接の親プロセスが発行する必要はない(initが対象の子プロセスを引き継ぐ)
プロセスは直接お互いに情報を交換することは出来ないが、Kernelを通じて情報の交換を行うことができる=プロセス間通信(IPC / Inter Process Communication)
- IPCの最も基本的なものとして"シグナル"がある
- 稼働中のプロセスに対してシグナルを送信することによりあらかじめ決めた振る舞いをさせることができる
Linuxが標準で利用できるシグナルの例
シグナル名 標準動作 通知内容 SIGHUP プロセス終了 端末のハングアップ検出 SIGINT プロセス終了 端末からの割り込み SIGQUIT コア・ダンプして終了 コア・ダンプ終了要求 SIGTERM プロセス終了 プロセスの終了要求 SIGKILL プロセス終了 プロセスの強制終了要求 SIGSTOP プロセスの実行中断 プロセスの実行中断要求 SIGSEGV コア・ダンプして終了 不正アドレスへのアクセス SIGCONT 無視 or 実行再開 中断状態のプロセス再開 SIGUSR1 プロセス終了 ユーザー定義のシグナル ※シグナルを受けた際の振る舞いはKernelに登録することにより変更できる=登録情報:シグナル・ハンドラ
kill()システム・コール
- プロセスが他のプロセスに対してシグナルを送る場合に使用するシステム・コール
※元々プロセスを終了させる仕組みだったためにkillという名称になっているが、現在ではシグナルは色々な用途に用いられる
※シグナルで送信できるのはシグナル番号のみ