スレッド、clone、futexとCMPXCHG

これは、スレッド(もしくはpthread)に関連するトピックについて、自分が過去に断続的に取ったメモのページです。理解を整理するためにまとめました。

pthreadの内部

pthreadscloneを呼び出す。これによりtask_structが作成される。

メモ:

  • pthread(POSIXスレッド)はlibcの一部。ほとんどのLinuxではglibc(GNU Cライブラリ)によって実装されている。

  • ユーザー空間で実装され、clone()futexなどのシステムコールを通じてカーネルとやり取りする。

  • fork()clone()を呼び出すが、異なるパラメータでの呼び出しになる。

メモ: libc vs カーネルのシステムコール

カーネルのシステムコールは移植性と安全性のためにlibcが標準インターフェイスとなる。man 2 [名前]はカーネルのシステムコールを説明し、man 3 [名前]はlibcの関数を説明するが、man 2でもライブラリセクションにlibcが表示されることが多い。

libc関数が単なるラッパーか、システムコールの上にさらにロジックを持っているかを調べるためには、その関数の内部や知識が必要。しかし、関数がman 3にしか存在しない場合、それはlibcの中でシステムコールをラップしているカスタム関数であることが分かる。

カーネルの観点

プロセスとスレッドの両方は、カーネル内でtask_structとして扱われる。

カーネルスケジュールの制御

ユーザーレベルスレッド

1:1モデルのみの言語

JavaやRustはm:nやグリーンスレッドのモデルを言語として提供せず、1:1のOSネイティブなスレッドの呼び出しのみを言語としてサポートする。

それに伴いこれらの言語ではm:n、グリーンスレッドやファイバーの機能は言語サポート外のライブラリとして実装、提供される。

同期機構

複数のスレッドがある場合、競合を処理する必要あり。pthreadはミューテックス条件変数セマフォなどの同期プリミティブを提供。

Futex

“Fast userspace mutex”の略。競合が発生した場合のみ、futexはカーネルとやり取りする。

メモ:

futexはカーネルの関与を最小限に抑えるように設計されているため、一見カーネルの一部ではないように見えるが、実際にはカーネルの構成要素。