🐧 Linux 総合学習プラットフォーム

システムコールの用語集(122語)

システムコールに関する Linux 用語を、読み・意味・補足つきでまとめました。

acceptあくせぷと
接続要求を1つ取り出し、その相手との通信用に新しいソケットを返すシステムコール。
待ち受け用ソケットはそのまま残り、実際の通信は戻り値の新しいソケットで行う——この2本立てが初学者の混同ポイント。要求が無ければ既定でブロックし、戻りと同時に相手のアドレスも得られる。
alarmあらーむ
指定した秒数の経過後に自プロセスへSIGALRMを送るよう予約するシステムコール。
alarm(5)なら5秒後にSIGALRMが届く。0を渡すと予約の取り消しになる。1プロセスに1つしか持てず精度も秒単位なので、細かい周期処理にはsetitimerやtimerfdが使われる。
async-signal-safeあしんくしぐなるせーふ
シグナルハンドラの中から呼んでも安全だと保証された関数の性質。
printfやmallocは内部状態を持つため、ハンドラ内で呼ぶとデッドロックやデータ破壊を招くことがある。write等のasync-signal-safeな関数だけを使うか、ハンドラではフラグを立てるだけにするのが定石。
bindばいんど
ソケットに自分側のアドレスとポート番号を結び付けるシステムコール。
サーバが「このポートで待つ」と宣言する手続きで、listenの前に行う。使用中のポートへのbindはEADDRINUSEで失敗する。クライアント側では通常省略され、カーネルが空きポートを自動で割り当てる。
closeくろーず
使い終えたファイルディスクリプタを閉じ、カーネル内の資源を解放するシステムコール。
閉じ忘れはファイルディスクリプタリークとなり、上限に達するとopenが失敗する。closeは番号を解放するだけで、同じ実体を指す記述子が他に残っていれば実体は開いたまま。プロセス終了時はカーネルが自動で全部閉じるが、長寿命のプログラムでは明示的に閉じる。
connectこねくと
クライアント側からサーバのアドレスへ接続を確立するよう要求するシステムコール。
TCPではここで3ウェイハンドシェイクが行われ、成功すればそのソケットでread/writeできる。UDPソケットに使うと接続ではなく「既定の宛先の設定」という意味になる点が紛らわしい。
Cライブラリ(libc)しーらいぶらり
printf や fopen などを提供する標準ライブラリ。
システムコールを使いやすく包んだ上の層。内部でバッファリングなどを行いつつ write/open を呼ぶ。glibc が代表。
dup2でゅーぷつー
ファイルディスクリプタを指定番号に複製するシステムコール。
あるディスクリプタの中身を、指定した別の番号(標準出力なら1、標準入力なら0)に複製する。パイプの端を標準入出力に差し替えて、コマンドを意識させずに連結するのに使う。
epollいーぽーる
多数のファイルディスクリプタの入出力可否をまとめて効率的に監視するLinux固有の仕組み。
epoll_createで監視用インスタンスを作り、epoll_ctlで対象を登録し、epoll_waitで準備完了のものだけを受け取る。selectやpollと違って監視対象が増えても性能が落ちにくく、大量接続を捌くサーバの定番。Linux専用でPOSIX標準ではない点に注意。
errnoえらーなんばー
直近のシステムコール失敗の原因を表す番号。
戻り値が -1 のときに参照する。ENOENT(ファイルなし)・EACCES(権限なし)など。perror/strerror で文章に直せる。
errnoえらーなんばー
システムコールやライブラリ関数が失敗した理由を示す番号が格納される特別な変数。
失敗(多くは戻り値-1)の直後にだけ意味を持ち、成功してもクリアされない点に注意。ENOENTやEACCESなどの定数と比較して原因を判定する。perrorやstrerrorで人間が読めるメッセージに変換できる。スレッドごとに独立した値を持つ。
execいぐぜっく
現在のプロセスを別のプログラムに置き換えて実行する。
execve が本体で、PIDは変わらず中身だけが入れ替わる。fork で作った子の中で呼ぶのが定番の流れ。
execえぐぜっく
現在のプロセスを別のプログラムで置き換えるシステムコール群の総称。PIDは変わらない。
execl・execv・execvpなど引数の渡し方が異なる一族があり、最終的にはすべてexecveに行き着く。成功するとメモリ内容は新しいプログラムに入れ替わり、呼び出し元へは戻らない。forkで子を作ってからexecするのが、UNIXで新しいプログラムを起動する基本形。
execveえぐぜくぶい
execファミリーの実体となるシステムコール。実行ファイル・引数・環境変数の3つを指定する。
他のexec系関数はすべてこの呼び出しへ変換されるラッパーである。成功すればプロセスのメモリ空間は指定プログラムで置き換わって戻ってこないため、execveの後ろに書いたコードはエラー時にしか実行されない。ファイルディスクリプタは原則として引き継がれる。
FIFOふぃふぉ
先入れ先出しの略。Linuxでは名前付きパイプを指す特殊ファイルの種別でもある。
First In First Outの略で、書き込んだ順に読み出されるデータ構造一般を指す。ls -lで先頭がpと表示されるFIFO特殊ファイルは名前付きパイプの実体で、mkfifoコマンドや関数で作る。
forkふぉーく
自分とほぼ同じ子プロセスを複製するシステムコール。
親には子のPID、子には 0 を返す。この戻り値で親子を区別する。多くは直後に exec で別プログラムへ置き換える。
ftokえふとっく
ファイルパスと数値からSystem V IPC用の共通キーを生成する関数。
実在するファイルのパスと1バイトのプロジェクトIDを組み合わせ、複数のプロセスが同じキーを再現できるようにする。同じキーでsemgetやshmgetを呼べば同じIPC資源にたどり着ける、という取り決めの道具。
glibcぐりぶしー
Linuxで標準的に使われるC標準ライブラリ。printfなどに加えシステムコールの入口も提供する。
GNU C Libraryの略。printfやmallocといったC標準関数だけでなく、openやforkなどシステムコールのラッパー関数、pthreadなどのPOSIX APIも提供する。アプリケーションは普段、glibcを経由してカーネルの機能を呼び出している。
htonsえいちとぅーえぬえす
16ビット値をホストバイトオーダからネットワークバイトオーダへ変換する関数。
host to network shortの略。sockaddr_inにポート番号を入れるときの定番で、忘れると意図と違うポートで待ち受けてしまう。32ビット用のhtonl、逆変換のntohs/ntohlと一族で覚える。
io_uringあいおーゆーりんぐ
カーネルと共有するリングバッファで入出力要求をやり取りする高速な非同期I/O機構。
提出用と完了用の2つのリングをユーザー空間とカーネルで共有し、システムコールの回数を大きく減らせる。Linux 5.1で導入され、epollや従来のAIOの限界を超える高性能サーバで採用が進んでいる。
ioctlあいおーこんとろーる
デバイス固有の操作を行うシステムコール。
read/writeでは表せないデバイス固有の設定・問い合わせを、コマンド番号で指定して実行する。fdとcmdを渡し、必要なら構造体へのポインタを追加で渡す。使える番号はデバイスドライバ次第。
ioctlあいおくとる
read/writeでは表現できないデバイス固有の操作を行うための万能システムコール。
端末の設定変更、ネットワークインタフェースの操作、フレームバッファの情報取得など、デバイスドライバごとに定義された要求番号と引数で多彩な制御を行う。何でもできる反面、要求ごとに仕様が異なるため各ドライバのドキュメント確認が欠かせない。
IPCあいぴーしー
プロセス間通信の総称。パイプ・共有メモリ・セマフォ・ソケットなどが含まれる。
プロセスはアドレス空間が分離されているため、データ交換には専用の仕組みが要る。速度重視なら共有メモリ、手軽さならパイプ、ネットワーク越しならソケットと、要件に応じて選び分ける。
ipcsあいぴーしーえす
System V IPC資源(共有メモリ・セマフォ・メッセージキュー)の一覧を表示するコマンド。
System V IPCの資源はプロセスが終了してもカーネル内に残り続ける。ipcsで残留を確認し、不要ならipcrmで削除する。IPCプログラムのデバッグと後始末の定番ツール。
iノードあいのーど
ファイルの実体を管理するデータ構造。サイズ・所有者・権限・データの位置などを保持する。
ファイル名はiノードに含まれず、ディレクトリが「名前→iノード番号」の対応表を持つ。この分離のおかげで、一つの実体に複数の名前を付けるハードリンクが実現できる。ls -iで番号を確認でき、statシステムコールで中身の情報を取得できる。
killきる
指定したプロセスへシグナルを送るシステムコール・コマンド。終了専用の命令ではない。
名前に反して役割は「シグナル送信」であり、送るシグナルは番号や名前で選べる。既定はSIGTERMで、kill -9はSIGKILLによる強制終了。SIGHUPで設定の再読み込みを促すなど、終了以外の合図にも日常的に使われる。
listenりっすん
ソケットを接続要求の受付状態にし、待ち行列の長さを指定するシステムコール。
TCPサーバの定型手順socket→bind→listen→acceptの3番目に当たる。backlog引数は接続要求を溜めておく待ち行列の上限で、あふれた接続要求は拒否や再送の対象になる。
lseekえるしーく
ファイルディスクリプタの読み書き位置(オフセット)を移動するシステムコール。
SEEK_SET(先頭基準)・SEEK_CUR(現在位置基準)・SEEK_END(末尾基準)で移動先を指定し、移動後の位置を返す。末尾より先へ移動して書き込むと穴の空いたスパースファイルができる。パイプやソケットには使えずESPIPEで失敗する。
manページ(セクション)まんぺーじ
マニュアルの分類番号。2=システムコール、3=ライブラリ関数。
man 2 open のように番号で指定する。同名でも別物のことがあるため番号指定が重要。一覧は man man で確認。
mmapえむまっぷ
ファイルやデバイスをメモリ空間に対応づけるシステムコール。
ファイルの一部をプロセスのアドレス空間に貼り付け、ポインタで直接読み書きできるようにする。read/writeの繰り返しを避けられる。使い終わりはmunmapで解除する。エラー時はMAP_FAILEDを返す。
mmapえむまっぷ
ファイルやデバイスをプロセスのアドレス空間に割り付け、メモリとして読み書き可能にするシステムコール。
マップした領域はポインタ経由で直接アクセスでき、read/writeを繰り返すより効率が良い場合がある。MAP_SHAREDを指定すると変更がファイルや他プロセスにも見え、共有メモリの実現手段にもなる。mallocの大きなメモリ確保も内部ではmmapが使われている。
mutexみゅーてっくす
共有資源を同時に1つのスレッドだけが使えるよう排他制御するロック機構。
pthread_mutex_lockで獲得、unlockで解放し、獲得中は他スレッドが待たされる。ロック順序の不統一はデッドロックの原因になる。カウンタを持つセマフォと違い、獲得した本人だけが解放するのが原則。
niceないす
プロセスの実行優先度(nice値)を変えてコマンドを起動するためのコマンド。
nice値は-20(高優先)から19(低優先)で、大きいほど「他に譲る=nice」。一般ユーザーは優先度を下げる方向のみで、上げるには特権が要る。実行中のプロセスに対してはreniceやsetpriorityを使う。
nice値ないすち
プロセスのCPU優先度を調整する-20〜19の値。大きいほど優先度が低く「行儀が良い」。
niceコマンドを付けて起動するか、reniceやsetpriorityで実行中に変更できる。優先度を上げる(負の値にする)には管理者権限が必要。バックグラウンドの重い処理に高いnice値を与えて、対話操作の快適さを守るのが典型的な使い方。
openおーぷん
パス名を指定してファイルを開き、以後の操作に使うファイルディスクリプタを返すシステムコール。
O_RDONLYやO_WRONLYで読み書きの向きを、O_CREATで新規作成を、O_APPENDで追記を指定する。O_CREAT時は第3引数でパーミッションを渡す。失敗すると-1を返しerrnoに理由が入るため、戻り値の確認が必須。
pauseぽーず
何かシグナルが配送されるまで、プロセスの実行を停止して待つシステムコール。
シグナル駆動のプログラムで「次のシグナルを待つ」ために使う。ただし条件判定と待機開始の間にシグナルが届く取りこぼし(競合)があり得るため、確実に待つにはsigsuspendの利用が推奨される。
perrorぴーえらー
直前のerrnoに対応するエラーメッセージを標準エラー出力へ表示するC標準の関数。
perror("open")のように呼ぶと「open: No such file or directory」の形式で出力される。エラー処理の第一歩として最も手軽で、システムコールの失敗直後に呼ぶのが作法。メッセージを文字列として取得したい場合はstrerrorを使う。
pipeぱいぷ
プロセス間の片方向通信路を作るシステムコール。
呼ぶと読み込み用と書き込み用のファイルディスクリプタが対で返る。書いた内容がもう片方から読める。forkと組み合わせて親子間通信に使う。シェルの | の実体。
pipeぱいぷ
書き込み口と読み出し口が対になった単方向の通信路を作り出すシステムコール。
戻り値として読み出し用と書き込み用の2つのファイルディスクリプタを得る。forkと組み合わせて親子プロセス間の通信に使うのが典型で、シェルの「|」もこの仕組みで実現されている。血縁のないプロセス間では使えず、その場合は名前付きパイプ(FIFO)を使う。
POSIXぽじっくす
UNIX系OSのAPIやコマンドの動作を統一した標準規格。従うことで移植性が得られる。
IEEEが定めた「Portable Operating System Interface」の略。openやreadなどのAPI、シェルの動作、コマンドの仕様を規定し、準拠して書いたプログラムはLinuxや他のUNIX系OSへ移植しやすくなる。epollなどLinux固有の機能はPOSIXの範囲外である点に注意。
PPIDぴーぴーあいでぃー
親プロセスのプロセスIDのこと。すべてのプロセスは自分を生んだ親の番号を保持する。
getppidで取得でき、ps -efのPPID列でも確認できる。プロセスツリーを辿る手掛かりになり、pstreeコマンドは親子関係を木構造で表示してくれる。親が先に終了するとPPIDはinit等の里親のPIDへ付け替えられる。
pthreadぴーすれっど
POSIXスレッドの略。C言語でスレッドの生成や同期を行うための標準API群の名前。
pthread_createやpthread_joinのほか、ミューテックス・条件変数などの同期機構を含む。ヘッダはpthread.hで、コンパイル時に-pthreadオプションを付けるのが作法。スレッド同士はプロセス内でメモリを共有するため、排他制御の設計が必須になる。
pthread_cond_signalぴーすれっどこんどしぐなる
条件変数で待っているスレッドを1つ起こすPOSIXスレッド関数。
待機側が居なければ通知は消えてしまい、後から待ち始めたスレッドには届かない。全員を起こすpthread_cond_broadcastとの使い分けと、条件フラグの更新をmutex保護下で行うことが要点。
pthread_cond_waitぴーすれっどこんどうぇいと
条件変数で通知が来るまでスレッドを眠らせて待つPOSIXスレッド関数。
mutexを引数に取り、待機開始と同時にロックを解放し、起床時に再獲得する動きが要点。スプリアスウェイクアップがあるため、必ずwhileループで条件を再確認しながら使う。
pthread_createぴーすれっどくりえいと
新しいスレッドを生成し、指定した関数をそのスレッドで実行させるpthreadの関数。
第3引数に開始関数、第4引数にその引数(void*)を渡す。生成されたスレッドは同じメモリ空間を共有しながら並行に動く。終了の回収はpthread_joinで行い、放置するとリソースが残るため、joinかdetachのどちらかを必ず選ぶ。
pthread_joinぴーすれっどじょいん
指定したスレッドの終了を待ち、その戻り値を受け取るpthreadの関数。資源も回収する。
プロセスにおけるwaitに相当し、終了したスレッドの資源を回収する役割も持つ。joinしないままだとスレッドの管理情報が残り続ける。回収が不要なスレッドはpthread_detachで切り離す設計にする。自分自身をjoinするとデッドロックになる。
readりーど
ファイルディスクリプタから指定バイト数を上限にデータをバッファへ読み込むシステムコール。
戻り値は実際に読めたバイト数で、要求より少ないことも普通にある。0はファイル終端(EOF)、-1はエラーを表しerrnoに理由が入る。ファイルだけでなくパイプやソケット、端末にも同じ形で使えるのがUNIXの統一的な入出力モデル。
semgetせむげっと
System Vセマフォ集合を作成または取得し、識別子を返すシステムコール。
ftokで作ったキーとIPC_CREAT等のフラグを渡し、以後の操作に使うセマフォ識別子を得る。1回の呼び出しで複数個のセマフォを持つ「集合」を確保できるのがSystem V流の特徴。
semopせむおぷ
セマフォの値を増減させ、資源の獲得や解放を行うシステムコール。
sembuf構造体に対象セマフォの番号と増減値を入れて渡す。負の値は獲得(足りなければブロック)、正の値は解放を意味する。複数の操作をまとめてアトミックに実行できるのがポイント。
shmatしむあっと
共有メモリセグメントを自プロセスのアドレス空間に貼り付けるシステムコール。
attach(アタッチ)の名の通り、shmgetで得た識別子を渡すと先頭アドレスが返り、以後は普通のポインタとして読み書きできる。使い終えたらshmdtで切り離す。最速のIPCだが、同期はセマフォ等で別途行う。
shmgetしむげっと
System V共有メモリセグメントを作成または取得し識別子を返すシステムコール。
キー・サイズ・フラグを指定して共有メモリの識別子を得る。実際にアクセスするにはshmatで自プロセスの空間に貼り付ける必要がある。作った資源はプロセス終了後も残るため、ipcsで確認し後始末する。
sigactionしぐあくしょん
シグナルハンドラを詳細なオプション付きで登録するシステムコール。signalより堅牢。
struct sigactionにハンドラ、ハンドラ実行中に追加でブロックするシグナル、SA_RESTARTなどのフラグを設定して登録する。古いsignal関数は環境によって挙動が異なるため、移植性と制御性の面から現在はsigactionの使用が推奨される。
SIGALRMしぐあらーむ
alarmやsetitimerで設定したタイマが満了したときに届くシグナル。
alarm(秒数)を呼ぶと指定時間後に自プロセスへSIGALRMが届き、既定動作はプロセス終了。ハンドラを登録してタイムアウト処理を実装するのが典型的な使い方で、sleepの内部実装にも関わってきた。
SIGHUPしぐはっぷ
端末の切断時にプロセスへ送られるシグナル。デーモンでは設定再読込の合図に使われる。
リモートログインが切れると、制御端末を失ったプロセス群にSIGHUPが届き既定では終了する。nohupで無視させたり、デーモンが「設定ファイルを読み直せ」という慣習的な合図として再利用したりする。
SIGINTしぐいんと
端末でCtrl+Cを押したときにフォアグラウンドのプロセスへ送られる割り込みシグナル。
既定動作はプロセスの終了。ハンドラで捕捉すれば、中断時の後片付けや「本当に終了するか」の確認といった独自処理を実装できる。キーボード由来という点で、killコマンド既定のSIGTERMや強制終了のSIGKILLと区別して覚えるとよい。
SIGKILLしぐきる
プロセスを問答無用で強制終了させるシグナル。捕捉も無視もブロックもできない。
kill -9で送られる番号9のシグナル。ハンドラを登録できないため後始末は一切実行されず、カーネルが直接プロセスを終わらせる。一時ファイルやロックが残る副作用があるので、SIGTERMで終了しない場合の最終手段として使う。
sigprocmaskしぐぷろっくますく
プロセスのシグナルマスクを変更し、特定シグナルの配送を一時的に保留する関数。
割り込まれたくない処理の間だけ対象シグナルをブロックし、終わったら解除するのが典型。ブロック中に届いたシグナルは破棄されず保留され、解除時に配送される。マルチスレッドではpthread_sigmaskを使う。
SIGSEGVしぐせぐぶ
許可されていないメモリ領域へアクセスしたときに送られるシグナル。セグフォの正体。
NULLポインタ参照、解放済み領域へのアクセス、配列の大幅な範囲外書き込みなどで発生し、既定ではコアダンプを伴って終了する。「Segmentation fault」の表示がこれ。コアダンプをgdbで開けば、どの行で落ちたかを特定できる。
SIGSTOPしぐすとっぷ
プロセスを一時停止させるシグナル。捕捉も無視もできない強制力を持つ。
SIGKILLと並んで、ハンドラ登録もブロックも不可能な特別なシグナル。停止したプロセスはSIGCONTで再開できる。Ctrl+Zで送られるSIGTSTP(こちらは捕捉可能)との違いがよく問われる。
SIGTERMしぐたーむ
プロセスに終了を「依頼」するシグナル。捕捉して後始末をしてから終わることができる。
killコマンドが既定で送るシグナル。受け取った側はハンドラで捕捉でき、ファイルの保存やリソース解放などの後始末をしてから終了できる。まずSIGTERMで丁寧に頼み、応じない場合に限りSIGKILLを使うのが運用の定石。
socketそけっと
通信の末端となるソケットを作成し、ファイルディスクリプタを返すシステムコール。
アドレスファミリ(AF_INET等)、型(SOCK_STREAM等)、プロトコルを指定して通信の入口を作る。得られたディスクリプタにbindやconnectを適用し、サーバやクライアントを組み立てていく。
statすたっと
ファイルのサイズ・権限・更新時刻などiノードが持つ情報を取得するシステムコール。
結果はstruct statに格納され、st_sizeやst_mode、st_mtimeなどのメンバで参照する。ファイル種別(通常ファイル・ディレクトリ等)の判定にはS_ISREGなどのマクロを使う。シンボリックリンク自身を調べたいときはlstatを使い分ける。
straceえすとれーす
プロセスが呼ぶシステムコールを記録・表示するツール。
「呼び出し名(引数) = 戻り値」の形で並ぶ。失敗時は errno 名も付く。-f で子も追跡、-e trace= で対象を絞れる。
straceえすとれーす
プロセスが発行するシステムコールと引数・戻り値を追跡して表示するデバッグツール。
strace ./a.outのように起動するか、-pで動作中のプロセスに接続して使う。openの失敗やどのファイルを読んでいるかがソース無しで分かるため、設定が読まれない・権限エラーといった調査に強力。ライブラリ関数の呼び出しを追うltraceとは対象が異なる。
UNIXドメインソケットゆにっくすどめいんそけっと
同一ホスト内のプロセス間通信に使うソケット。パス名で接続先を指定する。
ソケットAPIをそのまま使いながら、ネットワークスタックを通らないため高速。ファイルディスクリプタを相手プロセスへ受け渡せる点も特徴で、X11やDockerなど多くのデーモンが待ち受けに使う。
unlinkあんりんく
ファイル名とiノードの結びつきを解除するシステムコール。rmコマンドの中身にあたる。
削除するのは「名前」であり、iノードのリンクカウントが0になり、かつ誰も開いていない状態になった時点でデータ本体が解放される。開いたままunlinkすると名前は消えてもプロセスは読み書きを続けられるため、一時ファイルの手法としても使われる。
waitうぇいと
子プロセスの終了を待ち、その終了ステータスを回収するシステムコール。ゾンビ化を防ぐ。
回収によりゾンビプロセスの発生を防ぐのが重要な役割。引数のint型変数に終了情報が詰め込まれ、WIFEXITEDやWEXITSTATUSマクロで取り出す。どの子が終わるかは選べず、特定の子を待ちたいときはwaitpidを使う。
waitpidうぇいとぴっど
PIDを指定して特定の子プロセスの終了を待てる、waitの高機能版システムコール。
第1引数で待つ子を指定し、-1を渡せば任意の子でwait相当になる。WNOHANGオプションを付けると、終わった子がいなければブロックせず即座に戻るため、他の仕事をしながら定期的に子を回収するような使い方ができる。
writeらいと
バッファ内のデータをファイルディスクリプタの指す先へ書き出すシステムコール。
戻り値は実際に書けたバイト数で、要求より少ない「部分書き込み」が起こり得るため、確実に全部書くにはループが必要。書いた内容は一旦カーネルのバッファに載るだけなので、ディスクへの反映を保証したい場合はfsyncを併用する。
アトミックあとみっく
処理が途中で分割されず、外から見て一瞬で完了したように見える性質。
「読み出して加算して書き戻す」は3手に分かれるため、複数スレッドから同時に行うと更新が失われることがある。アトミック操作やロックで不可分性を保証するのが並行プログラミングの基本になる。
カーネルモードかーねるもーど
カーネルが動作するCPUの特権モード。ハードウェアやメモリ全体へ制限なくアクセスできる。
システムコールや割り込みをきっかけにCPUがこのモードへ移行し、カーネルのコードが実行される。ユーザモードとの往復には相応のコストがかかるため、システムコールの発行回数を減らすことが性能改善につながる場面が多い。
カーネル空間かーねるくうかん
OSの中核が動く、特権を持つ領域。
ハードウェア制御やメモリ管理を担う。ユーザ空間とは隔離され、境界はシステムコールでのみまたげる。
クリティカルセクションくりてぃかるせくしょん
複数のスレッドが同時に実行してはならない、共有資源を触るコード区間。
この区間をロックで守り、同時に入れる実行主体を1つに制限することで競合状態を防ぐ。区間は短いほどよく、長く取りすぎると並列性が落ちる。ロックの取り忘れや解放忘れが典型的なバグの源になる。
コアダンプこあだんぷ
プロセスが異常終了した瞬間のメモリ内容を書き出したファイル。事後デバッグに使う。
SIGSEGVなどで異常終了したときに生成され、gdbで実行ファイルと一緒に読み込むと、クラッシュ時のスタックトレースや変数の値を調べられる。生成にはulimit -cの設定が必要で、systemd環境ではcoredumpctlで一覧・取得できる。
コピーオンライトこぴーおんらいと
fork直後は親子でメモリを共有し、どちらかが書き込んだ時に初めて複製する最適化技法。
forkは建前上メモリ全体を複製するが、実際にはページを共有して読み取り専用にしておき、書き込みが起きたページだけをコピーする。これによりfork自体は巨大なプロセスでも高速に完了する。直後にexecする典型パターンでは複製がほとんど発生せず無駄がない。
コンテキストスイッチこんてきすとすいっち
CPUが実行する処理を別のものへ切り替える動作。
CPUが実行するプロセス(やスレッド)を別のものへ入れ替える動作を指す。システムコールで起きるユーザ→カーネルのモード切替は同一プロセス内の権限切替であり、コンテキストスイッチとは区別される。頻発すると性能に影響する。
コンテキストスイッチこんてきすとすいっち
CPUが実行対象のプロセスやスレッドを切り替える処理。レジスタ等の状態を退避・復元する。
スケジューラが、タイムスライスの消費や入出力待ちによるブロックを機に発生させる。切り替え自体にレジスタ退避のコストがかかるうえ、キャッシュの効率も下がるため、頻発すると性能が落ちる。vmstatやpidstatで発生回数を観測できる。
シグナルしぐなる
プロセスに非同期でイベントを知らせる仕組み。
Ctrl+CのSIGINTや異常アクセスのSIGSEGVなど、名前と番号を持つ。既定動作は終了が多いが、sigactionでハンドラを登録して挙動を変えられる。SIGKILLとSIGSTOPだけは捕捉も無視もできない。
シグナルしぐなる
プロセスへ非同期に届く軽量な通知。受け取ると処理に割り込んで既定動作やハンドラが走る。
Ctrl+Cによる割り込み(SIGINT)や不正メモリアクセス(SIGSEGV)など、イベントの発生をプロセスへ伝えるUNIXの基本機構。既定動作は終了やコアダンプなどシグナルごとに決まっており、sigactionでハンドラを登録して動作を変えられる。SIGKILLとSIGSTOPだけは変更できない。
シグナルセットしぐなるせっと
複数のシグナルをひとまとめに扱うためのsigset_t型のビット集合データ。
sigemptysetで空にし、sigaddsetで対象シグナルを加えるといった専用関数で操作する。sigprocmaskのブロック対象指定やsigactionのマスク指定など、シグナルAPI全般の引数として登場する。
シグナルハンドラしぐなるはんどら
シグナル受信時に呼ばれる関数。
sigactionで登録しておくと、対応するシグナルが届いたときにその関数が実行される。後始末をしてから終了するなどの制御に使う。ハンドラ内ではasync-signal-safeな関数だけを使うのが安全。
シグナルハンドラしぐなるはんどら
特定のシグナルを受け取ったときに呼び出されるよう、あらかじめ登録しておく関数。
sigactionで登録し、SIGTERM受信時の後始末やSIGINTの無視といった独自動作を実現する。ハンドラは通常処理の途中に割り込んで実行されるため、中で呼べるのはasync-signal-safeな関数に限られる。printfやmallocの呼び出しは未定義動作の危険がある。
シグナルマスクしぐなるますく
配送を一時的に保留(ブロック)するシグナルの集合。プロセスやスレッドごとに保持される。
sigprocmask(スレッドではpthread_sigmask)で設定し、重要な処理の途中にシグナルが割り込むのを防ぐ。ブロック中に届いたシグナルは捨てられずに保留され、解除した時点で配送される。SIGKILLとSIGSTOPはブロックできない。
システムコールしすてむこーる
アプリがカーネルに処理を依頼する公式の窓口。
ファイル入出力・プロセス生成・通信など、特権が要る処理はすべてシステムコール経由で行う。open・read・write・fork などが代表例。
システムコール番号しすてむこーるばんごう
各システムコールに割り当てられた識別番号。
カーネルは呼びたいシステムコールを名前ではなく番号で受け取る。番号はアーキテクチャによって異なり、ヘッダで定義されている。glibcのラッパがこの番号を積んでトラップを起こす。
スケジューリングすけじゅーりんぐ
実行可能なプロセスやスレッドのどれにCPU時間を割り当てるかをカーネルが決める仕組み。
Linuxの通常タスクは公平型のスケジューラが優先度(nice値)を加味してCPUを配分する。ほかにリアルタイム用のFIFOやラウンドロビンといったポリシーもあり、sched_setschedulerで変更できる。組込み分野では応答時間の保証と関わる重要テーマ。
スケジューリングポリシーすけじゅーりんぐぽりしー
カーネルがどの方針でプロセスにCPU時間を配るかを決める規則の種類。
Linuxでは通常のSCHED_OTHERに加え、リアルタイム用のSCHED_FIFOやSCHED_RR等があり、sched_setschedulerで切り替える。リアルタイムポリシーの優先度は絶対的で、通常プロセスより常に先に実行される。
スプリアスウェイクアップすぷりあすうぇいくあっぷ
条件変数などで待機中のスレッドが、通知が無いのに誤って起こされる現象。
pthread_cond_waitは通知されていなくても戻ることがあると仕様で認められている。そのため待機はifではなくwhileループで条件を再確認する形で書くのが必須の作法となる。
セマフォせまふぉ
カウンタを使って資源への同時アクセス数を管理する同期の仕組み。IPCにも使える。
獲得でカウンタを減らし、0なら空きが出るまで待つ。解放で増やす。初期値1ならミューテックス相当、Nなら「同時にN個まで」の制限に使える。POSIXセマフォ(sem_wait等)とSystem Vセマフォ(semop等)の2系統があり、プロセス間の同期にも使える点がpthreadミューテックスとの違い。
ゾンビプロセスぞんびぷろせす
終了したが親に回収されず残る子プロセス。
親が wait で終了ステータスを受け取ると消える。回収を怠るとプロセス表に残り続ける。
ゾンビプロセスぞんびぷろせす
終了済みだが親がwaitで回収していないため、終了情報だけが残っているプロセス。
プロセスは終了しても、終了ステータスを親に伝えるためプロセステーブルの項目が残る。親がwait系を呼ぶとこの項目が消える。psでZ状態と表示され、すでに死んでいるのでkillでは消せない。大量に溜まるとPIDを圧迫するため、親が確実にwaitするのが作法。
デタッチでたっち
スレッドを切り離し、終了時に資源が自動回収されるようにする操作。
pthread_detachしたスレッドはpthread_joinで待ち合わせできなくなる代わりに、終了と同時に資源が解放される。joinもdetachもしないと終了済みスレッドの資源が残り続けるので注意。
デッドロックでっどろっく
複数の実行主体が互いのロック解放を待ち合い、全員が永遠に進めなくなる状態。
典型例は、スレッドAがロック1を持ってロック2を待ち、スレッドBがロック2を持ってロック1を待つ相互待ち。発生すると外部から強制終了するしかない。全員が同じ順序でロックを取る、複数ロックの同時保持を避ける、が定番の予防策。
デバイスファイルでばいすふぁいる
デバイスをファイルとして見せる特殊ファイル。
/dev の下にあり、open/read/write/ioctlでハードウェアを操作できる。/dev/rtc0のような時計デバイスなどがあり、多くは操作にroot権限を要する。
トラップ(ソフト割込み)とらっぷ
ユーザ空間からカーネルへ制御を渡すCPUの仕掛け。
特別なCPU命令によって特権レベルを上げ、カーネルの入口へ制御を移す。システムコールはこのトラップを経由してカーネルに入り、処理後にユーザ空間へ戻る。
ハードリンクはーどりんく
同じiノードを指す別名を追加する仕組み。実体は一つのまま複数のファイル名を持てる。
lnコマンドやlinkシステムコールで作成し、どの名前からも同一の実体を読み書きできる。iノードのリンクカウントが名前の数を記録し、すべての名前がunlinkされて初めてデータ本体が解放される。別ファイルとしてパスを保持するシンボリックリンクとは仕組みが違う。
バイトオーダーばいとおーだー
複数バイトの数値をメモリに並べる順序。ビッグ/リトルエンディアンがある。
上位バイトから置くのがビッグエンディアン、下位からがリトルエンディアン。x86やARM(通常設定)はリトルだが、ネットワークのプロトコルはビッグが標準のため、通信プログラムでは変換が必須になる。
ビジーループびじーるーぷ
条件が成立するまでCPUを回し続けて待つ待機方法。スピンとも呼ぶ。
実装は簡単だがCPU時間と電力を浪費するため、ユーザー空間では条件変数やselect等のブロッキング待機が基本。ごく短い待ちやスリープできない文脈では、スピンが合理的な場合もある。
ファイルディスクリプタふぁいるでぃすくりぷた
開いたファイルを指す小さな整数(0以上)。
open が返し、read/write/close で対象指定に使う。0=標準入力, 1=標準出力, 2=標準エラー出力が最初から開かれている。
ファイルディスクリプタふぁいるでぃすくりぷた
プロセスが開いたファイルやソケットを識別するためにカーネルが割り当てる小さな整数。
openやsocketの戻り値として得られ、以降のread・write・closeはこの番号で対象を指定する。0は標準入力、1は標準出力、2は標準エラー出力と予約されている。ファイルもパイプもソケットも同じ番号の仕組みで扱えるのがUNIXの設計の要。
ファイルディスクリプタリークふぁいるでぃすくりぷたりーく
closeを忘れてファイルディスクリプタを溜め続けるバグ。上限に達すると新規に開けなくなる。
プロセスが開ける数には上限(ulimit -nで確認)があり、リークが続くとopenやsocketがEMFILEで失敗し始める。長時間動き続けるサーバプログラムで顕在化しやすい。lsofや/proc/<PID>/fdを見ると、開きっぱなしの記述子を特定できる。
プロセス間通信ぷろせすかんつうしん
独立したメモリ空間を持つプロセス同士がデータをやり取りするための仕組みの総称。IPC。
パイプ・FIFO・共有メモリ・メッセージキュー・セマフォ・ソケットなど多くの手段があり、速度・通信の向き・プロセス間の関係(親子か無関係か)・ホストをまたぐかで使い分ける。プロセスは互いのメモリを直接見られないため、カーネルの仲介が必要になるのが根本の理由。
ページぺーじ
メモリ管理の固定サイズ単位。
OSはメモリをページという固定サイズの区画で管理する。多くの環境で4096バイト。mmapのoffsetはこのサイズの倍数に揃える必要がある。getconf PAGESIZEで値を確認できる。
ページぺーじ
カーネルが仮想メモリを管理する最小単位。多くの環境で4KiBの固定サイズを持つ。
仮想メモリはページ単位で物理メモリに対応付けられ、mmapの割り付けやコピーオンライトの複製もページ単位で行われる。存在しないページに触れるとページフォルトが発生し、カーネルが割り当てや読み込みを行うか、不正アクセスならSIGSEGVを送る。getconf PAGESIZEで確認できる。
マルチスレッドまるちすれっど
1つのプロセスの中で複数の実行の流れ(スレッド)を同時に走らせる方式。
スレッド同士はアドレス空間を共有するため、データの受け渡しが軽い反面、共有データへの同時アクセスをmutex等で守る必要が生じる。空間が分離されるマルチプロセスとの使い分けが設計の要点。
ミューテックスみゅーてっくす
一度に一つの実行主体だけがロックを獲得できる、排他制御の最も基本的な仕組み。
pthreadではpthread_mutex_lockとpthread_mutex_unlockで囲んだ区間を、同時に一つのスレッドしか実行できなくする。ロックしたスレッド自身が解放するのが原則で、unlock忘れは他スレッドの永久待ちを招く。相互排他(mutual exclusion)の略。
メッセージキューめっせーじきゅー
型付きのメッセージ単位でデータを送受信できるプロセス間通信の仕組み。
System V版はmsgget/msgsnd/msgrcvで操作し、mtypeで受信するメッセージを選別できる。バイト列が切れ目なく流れるパイプと違い、メッセージの区切りが保たれるのが利点。POSIX版(mq_*)もある。
メモリリークめもりりーく
mallocなどで確保したメモリを解放し忘れ、使用量が増え続ける不具合。
長時間動き続ける組込み機器やデーモンでは致命傷になりやすい。valgrindなどの検出ツールで確保と解放の対応を確認する。プロセス終了時にはOSが全て回収するため、短命なコマンドでは顕在化しにくい。
ユーザモードゆーざもーど
アプリケーション実行時のCPUの動作モード。ハードウェアへの直接アクセスが制限される。
CPUには特権レベルがあり、通常のプログラムは権限の低いユーザモードで動く。禁止された操作(デバイス制御や他プロセスのメモリ参照など)が必要なときは、システムコールを発行してカーネルモードへ切り替えてもらう。この分離がOSの保護機構の土台になっている。
ユーザランドゆーざらんど
カーネルの外側でアプリやライブラリが動く領域、およびそのソフトウェア群の総称。
シェル・コマンド・ライブラリ・アプリケーションはすべてユーザランドで動作する。ここからはハードウェアを直接操作できず、ファイル操作やメモリ確保などはシステムコールを通じてカーネルに依頼する。CPUの動作モードを指すユーザモードと対応する概念として語られる。
ユーザ空間ゆーざくうかん
アプリが動く、権限を制限された領域。
ハードウェアやカーネルのメモリに直接触れない。必要な処理はシステムコールでカーネルに依頼する。
ラッパー関数らっぱーかんすう
別の関数や低レベル機能を包み、扱いやすい形にして提供する関数のことを指す。
システムコールの文脈では、glibcが提供するopenやwriteなどの関数を指す。CPU依存の呼び出し手順(レジスタ設定やトラップ命令)を隠してC言語の関数として呼べるようにし、失敗時のerrno設定まで面倒を見る。manの2章にある関数は実際にはラッパー経由で呼ばれている。
競合状態きょうごうじょうたい
複数の処理の実行タイミング次第で結果が変わってしまう不具合。レースコンディション。
典型例は、2つのスレッドが同じ変数へ同時にカウントアップして片方の更新が失われるケース。タイミング依存でたまにしか起きず再現性が低いため、デバッグが非常に難しい。排他制御やアトミック操作で「同時に触らせない」ことが根本対策になる。
共有メモリきょうゆうめもり
複数のプロセスが同じ物理メモリ領域を直接読み書きできるようにするIPCの一種。
shmget/shmatやmmap(MAP_SHARED)で実現し、カーネルを介したコピーが不要なため最速のIPCとされる。ただし同時書き込みの調停は自前で行う必要があり、セマフォ等との併用が前提。使い終えた領域が残留しやすく、ipcsで確認してipcrmで掃除する。
孤児プロセスこじぷろせす
親プロセスが先に終了してしまった子プロセス。init等が新しい親となって引き取る。
親を失った子はカーネルによってPID 1(initやsystemd)などの里親に付け替えられ、終了時の回収も里親が行う。終了済みなのに回収されないゾンビプロセスとは別物で、孤児は生きて動き続けている。デーモン化の手順では意図的に孤児を作ることもある。
子プロセスこぷろせす
forkで親プロセスの複製として生成されたプロセス。親とは別のPIDを持って独立に動く。
生成直後はメモリ内容やファイルディスクリプタが親のコピーで、forkの戻り値(子では0)だけで親子を区別する。多くの場合、続けてexecを呼んで別プログラムに変身する。シェルがコマンドを実行する仕組みもこのfork+execそのもの。
終了ステータスしゅうりょうすてーたす
プロセスが終了時に親へ返す0〜255の数値。0が成功、それ以外が失敗を表す慣習。
mainのreturn値やexitの引数がこれになり、親プロセスはwait系で受け取る。シェルでは直前のコマンドの値を$?で参照でき、if文やスクリプトの分岐に使われる。シグナルで終了させられた場合、シェルの$?は128+シグナル番号になる慣習がある。
条件変数じょうけんへんすう
条件が満たされるまでスレッドを眠らせ、他のスレッドからの通知で起こす同期機構。
pthread_cond_waitで待ち、pthread_cond_signalやbroadcastで起こす。必ずミューテックスとペアで使い、通知なしに目覚めるスプリアスウェイクアップに備えて条件はwhileループで再確認するのが鉄則。CPUを浪費するビジーループを、眠って待つ方式に置き換えられる。
親プロセスおやぷろせす
forkで別のプロセスを生み出した側のプロセス。子の終了をwaitで回収する責任を持つ。
Linuxのプロセスはすべて親子関係のツリーを成し、親のPIDはPPIDとして子から参照できる。親は子の終了ステータスをwait系で回収する義務があり、怠るとゾンビプロセスが残る。親が先に終了すると子は孤児プロセスとしてinit等に引き取られる。
排他制御はいたせいぎょ
共有資源へ複数の実行主体が同時にアクセスしてデータを壊すことを防ぐ制御の総称。
ミューテックスやセマフォで「一度に一人だけ」を保証し、競合状態を防ぐ。保護すべき区間はクリティカルセクションと呼ばれる。かけ忘れはデータ破壊に、かけすぎは性能低下やデッドロックにつながるため、粒度の設計が腕の見せどころになる。
名前なしパイプなまえなしぱいぷ
pipeシステムコールで作る、親子プロセス間だけで使える一方向の通信路。
読み口と書き口のファイルディスクリプタの組として得られ、forkで子プロセスに引き継ぐことで通信する。シェルの「|」の実体でもある。名前を持たないため、無関係なプロセスとは共有できない。
名前付きパイプなまえつきぱいぷ
ファイルシステム上に名前を持ち、無関係なプロセス同士でも使えるパイプ。
mkfifoで作成し、通常のファイルと同様にopenして読み書きする。親子関係が必要な名前なしパイプと違い、パス名さえ共有すれば任意のプロセス間で通信できる。FIFOとも呼ばれる。

▶ 学習アプリで「引く」を使う