わたしは
ebikunです。CARTA HOLDINGSというアドテクなどなどをやっている愉快な企業の新卒内定者であります。
会社のお金でGoならわかるシステムプログラミング第2版を買ってもらったので今日はそのwrap upを書いていこうと思います。本の内容上Go言語特有の解説がまぁまぁなウェイトで入っていましたが、ここではそれは割愛しメインとなるシステムプログラミングの内容と自身の興味にフォーカスします。
この本では
PHPなどのプログラミング言語はファイルを開く、メモリを確保するなどの様々なOSの機能を実行時に呼び出している。このようにOSの機能を呼び出すことをシステムプログラミングという。本書はシステムプログラミングについてOSが内部でどんな仕事をしているのかをGo言語を題材に見ていく。
5章 システムコール
- システムコールとは「特権モードでOSの機能を呼び出すこと」
- OSの仕事はメモリなどの各種資源の管理とファイル読み書きなどの外部入出力機能の提供である
- プログラムの実行単位のことをプロセスという
- 昔はプロセス管理はOSの仕事ではなかった
- Windows3.0ではプロセスが別のプロセスのメモリにもアクセスできた
- Windows3.1ではプロセスがCPUを別のプロセスに自分で回していた
- 今はプロセスの管理もOSの仕事の1つである
- OSの仕事を支えるハードウェアであるCPUには「動作モード」という仕組みがある
- 動作モードはソフトウェアによって変わり、それによって実行して良いハードウェアとしての機能を制限している
- 動作モードには「特権モード」と「ユーザモード」がある
- OSはユーザによる強制終了などの強い操作を実行できなければならないので、その他のアプリのプロセスより強い特権モードで起動する
- 逆に一般のアプリケーションは強い操作ができないユーザモードで起動する。
- 動作モードによって、できる操作がCPUのハードウェアレベルで切り分けられている!
- しかし一般アプリからもメモリアクセスや外部入出力をしたい!(それはそう)
- そこで システムコール を使ってユーザモードのアプリから特権モードでしか使えない機能を使っちゃおうってわけ
- システムコールを呼び出すと呼び出された側は特権モードで動作する
じゃあシステムコールがないとどうなるのか
- 実はCPUの命令自体はユーザモードでもほとんど使える
- でも計算結果をメモリやファイルに格納したりネットワーク通信で外部に送信したり画面に表示したりするのは特権モードにしかできない。
- だから特権モードを呼べるシステムコールがないと 計算結果が無駄になる!
- 実際にはシステムコールがなければ計算のためのデータをメモリから読み込んだり、計算を行うためのメモリを確保したりプロセスを立ち上げることもできない(ので 計算も満足にできない)
POSIX
- OS間で共通なシステムコールのインターフェース
- 実際にはC言語の関数シグネチャとして定義されている
- Go言語もPOSIXのインターフェースに準拠している
- ただしsyscallパッケージ(システムコールのパッケージ)以下のドキュメントはGo言語にはほぼない。必要ならC言語のシステムコールのドキュメントを参照すること。
- システムコール以下のLinuxカーネルはC言語で動作する
ちなみに
- POSIXは「システムコールのOS間のポータビリティを維持する」ことが目的
- よって本来ならPOSIXに準拠しているGo言語が、各OSのシステムコールをいちいち番号指定して呼び出すのは推奨されない。(C言語の関数使えって話。)だがそれによってクロスコンパイルが容易になり様々なOS上で動くバイナリが簡単に作れるようになった。が、システムコールをいちいち番号指定して呼ぶとなぜポータビリティが損なわれるのかはよくわからなかった。
- が、とにかくGo言語はシステムコールの各OS対応を自力で頑張っていて、それによってクロスコンパイルが容易になっている。
19章 Go言語とコンテナ
まずは仮想化一般についての話。
- 仮想化とは「ホストOSの上に複数のOSやシステムを安全に共存させて、ピークの異なる複数のサービスをまとめるなどして効率的にハードウェアを使う」ための技術
- 特に複数のOSが共存できるというのがmiso。
仮想化はいくつかの分類方法がある。
-
エミュレーション:CPUを完全にエミュレートする。ホストとは異なるアーキテクチャのCPUを使えるが、パフォーマンスは大きく落ちる
-
ネイティブ仮想化:CPUのエミュレーションを行わない高速な仮想化。
-
完全仮想化:ホストOSの上にハイパーバイザを入れてその上で複数のゲストOSを動かす。センシティブな処理はハイパーバイザが割り込んで処理するのでゲストOSは自分が仮想化されていることを意識しなくて良いが、割り込みは発生するのでパフォーマンスは悪い。ただしCPUの進化により現在ではほぼ克服されている。
-
準完全仮想化:ハードの上に直接ハイパーバイザを入れてその上でホストOSとゲストOSを同列に動かす。ゲストOSは自分が仮想化されていることを意識しないといけない。センシティブな処理はハイパーバイザを呼び出すようにする。割り込みが発生しないので完全仮想化よりはパフォーマンス面で有利。