「Goならわかるシステムプログラミング」の4章を読んだのでメモ。4章はチャネル、5章はシステムコールについて
4章
チャネルとは何か
本文から引用
ソフトウェアの世界には、キュー(queue)と呼ばれるデータ構造があります。 キューは、最初に投入したデータが最初に出力される「First-in, First-out」(FIFO)型 のデータ構造です。Go言語のチャネルは、このキューに並列処理用の「並列でアク セスされても正しく処理される」ことを保証する機能を組み合わせたものです。
・チャネルは、データを順序よく受け渡すためのデータ構造である ・チャネルは、並列処理されても正しくデータを受け渡す同期機構である ・チャネルは、読み込み・書き込みで準備ができるまでブロックする機能である
チャネルの書き方
宣言
// バッファなし tasks := make(chan string) // バッファあり tasks := make(chan string, 10)
データ送受信
// データを送信 tasks <- "cmake .." tasks <- "cmake . --build Debug" // データを受け取り task := <-tasks // データ受け取り&クローズ判定 task, ok := <-tasks // データを読み捨てる場合は代入分も不要 <-wait
チャネルの操作と振る舞いとして4パターン挙げられていて
- チャネル<-値で送信
- 変数:=<-チャネルで受信
- 変数,ok:=<-チャネルで受信
- for変数:=rangeチャネルで受信
最初の3つはまあわかりやすいと思うけど4つ目が個人的にはすぐに飲み込めなかった。
このコード↓はfor文で使う例だけどチャネル(result)に値を入れるたびにfor文を回してcloseにチャネルを入れるとループが閉じる例だけどこういうのはもうちょっと慣れないと読み書きできないかな。
pythonやjavascriptのジェネレータがこんな感じらしいけどそっちも使えてないのでjsでループ書くとき使ってみるかな。。
func primeNumber() chan int { result := make(chan int) go func() { result <- 2 for i := 3; i < 100000; i += 2 { l := int(math.Sqrt(float64(i))) found := false for j := 3; j < l + 1; j += 2 { if i%j == 0 { found = true break } } if !found { result <- i } } close(result) }() return result } func main() { pn := primeNumber() for n := range pn { fmt.Println(n) } }
5章
システムコールとは何か
多くのOSでは、システムコールを介して、特権モードでのみ許 されている機能をユーザーモードのアプリケーションから利用できるようにしている
- システムコールがなければ、計算した結果を画面に出力することはできません。 ターミナルからプログラムを実行している場合も、IDEから実行している場合も、 出力先は別のプロセスです。特権モードのみで許可されるプロセス間通信の機能 を使わなければ、結果を伝達することはできません。
- システムコールがなければ、計算した結果をファイルに保存することはできませ ん。特権モードのみで許可されるファイルの入出力機能を使わなければ、結果を ファイルに保存して、他のプログラムから読むことはできません。
- システムコールがなければ、計算した結果を共有メモリに書き出すこともできま せん。共有メモリ機能を使えば、他のプログラムから計算結果を参照することが できますが、特権モードでなければ共有メモリを作成することができません。
- システムコールがなければ、計算した結果を外部のウェブサービスなどに送信す ることもできません。外部のウェブサービスなどへの通信も、カーネルが提供す る機能がなければ利用できません。
この章は実際にGoのコードを書くと言うよりもOSの世界(C言語)の解説的な内容だった。