Go言語による並行処理

[cover photo]
TOPICS
Programming
発行年月日
PRINT LENGTH
256
ISBN
978-4-87311-846-8
原書
Concurrency in Go 
FORMAT
Print PDF EPUB
Ebook
3,080円
Ebookを購入する
Print
3,080円

シンプルな言語仕様と手厚い並行処理機能で多くのプログラマの心を捉えるGo言語。いまではサーバーサイドでのプログラミングやコンテナツールの実装言語など、さまざまな分野で活用されています。本書は、Goの並行処理の設計哲学、言語の機能、また実際のプログラミングテクニックや並行処理の使い方、システムに導入する際のベストプラクティスとパターン、その内部構造までを簡潔にまとめた書籍です。
普段からGoでプログラミングをしているプログラマや、並行処理について学習したいプログラマが、新たな知識を身につけるのに良い一冊となるでしょう。

本書のサポートリポジトリ

正誤表

ここで紹介する正誤表には、書籍発行後に気づいた誤植や更新された情報を掲載しています。以下のリストに記載の年月は、正誤表を作成し、増刷書籍を印刷した月です。お手持ちの書籍では、すでに修正が施されている場合がありますので、書籍最終ページの奥付でお手持ちの書籍の刷版、刷り年月日をご確認の上、ご利用ください。

正誤表(1刷)

p.4 1.1 2段落目

なぜShutterがそのような強い言葉を使ったのかを知るためには、

なぜSutterがそのような強い言葉を使ったのかを知るためには、

補足

人名のSutterがShutterになっていました。(2018.10.29 ePub版、mobi版で修正済み)

p.4 1.2 1段落目

実際に、本書のサンプルコードをでも

実際に、本書のサンプルコードでも

補足

余計な「を」が入っていました。(2018.10.29 ePub版、mobi版で修正済み)

p.9 サンプルコード

      if value == 0 {
          fmt.Printf("the value is %v.\n", value)
      } else {
          fmt.Printf("the value is %v.\n", value)
      }

  

      if value == 0 {
          fmt.Printf("the value is 0.\n")
      } else {
          fmt.Printf("the value is %v.\n", value)
      }

  

補足

サンプルコード自体は原文のとおりであり、また出力結果自体は変わりがないですが

  • 直前のサンプルコードとの比較において不自然であること
  • if節とelse節で同じ内容にするならば、そもそも意味がないこと

から、これは誤りであると判断されます。ただし、本家errataにないため、脚注として処理します。 またソースコード内の変数 value ですが、直後の説明で「 data 変数」と説明しているので変数名は data のほうが良いでしょう。 (2018.10.29, 2018.11.14 ePub版、mobi版で修正済み)

p.10 1.2.4 3行目

また別の問題に取り組まければいけません。

また別の問題に取り組まなければいけません。

補足

「な」が抜けていました。(2018.10.29 ePub版、mobi版で修正済み)

p.31 2.3 脚注4

ここでは「コードをうまく部品としてカプセル化しやすいような言語のモジュール機能や型システムなどを評価する言葉として使用しています。

ここでは、コードをうまく部品としてカプセル化しやすいような言語のモジュール機能や型システムなどを評価する言葉として使用しています。

補足

鉤括弧が不必要でした。(2018.10.29 ePub版、mobi版で修正済み)

p.48 3.2.1 最終行

Add の呼び出しは監視対象のゴルーチンの外で行われていてることに注目してください。

Add の呼び出しは監視対象のゴルーチンの外で行われていることに注目してください。

補足

余計な「て」が入っていました。(2018.10.29 ePub版、mobi版で修正済み)

p.51 3.2.2 3段落目

すべてがメモリの読み込みと書き込みの 両方を 必要にするわけではないでしょう。

すべてがメモリの読み込みと書き込みの 両方を 必要とするわけではないでしょう。

補足

「必要とする」が「必要にする」となっていました。(2018.10.29 ePub版、mobi版で修正済み)

p.52 3.2.2 サンプルコードの解説

  1. 生産者を1秒スリープさせて

  1. 生産者を1ナノ秒スリープさせて

補足

原文からの間違い。サンプルプログラム内では time.Sleep(1) となっているので1ナノ秒が正しく、出力結果を見ても1ナノ秒に設定しての結果と思われます。(2018.10.28時点で本家errata未登録、2018.10.29 ePub版、mobi版で修正済み)

p.52 3.2.2 サンプルコードおよび出力結果

下記それぞれに RWMutext と余計な t が入っている

  • fmt.Fprintf(tw, "Readers\tRWMutext\tMutex\n")
  • Readers RWMutext Mutex

  • fmt.Fprintf(tw, "Readers\tRWMutex\tMutex\n")
  • Readers RWMutex Mutex

補足

原著より存在する間違いでした。(2018.10.26 ePub版、mobi版では修正済み)

p.57 3.2.3 サンプルコードの解説

  1. これはプログラムが stdout への書き込む前に終了してしまわないように

  1. これはプログラムが stdout へ書き込む前に終了してしまわないように

補足

余計な「の」がありました。(2018.10.29 ePub版、mobi版で修正済み)

p.57 3.2.3 サンプルコードの解説の数字と説明文の対応

内容

解説のための番号と解説の内容が合致していない。以下のように番号と説明文の対応を変える必要がある。

  • ③→④の説明文
  • ④→⑤の説明文
  • ⑤→⑥の説明文
  • ⑥→⑦の説明文
  • ⑦→③の説明文

補足

原著よりの誤りです。(2018.10.29現在errata未報告、2018.10.29 ePub版、mobi版で修正済み)

p.66 3.3 1段落目

後ほど、なぜその重要性を説明します。

後ほど、その重要性を説明します。

補足

余計な「なぜ」が入っていました。(2018.10.29 ePub版、mobi版で修正済み)

p.70 3.3 ページ2つ目のサンプルコード解説の数字

①チャネルを閉じます。これによって…(後略)

②チャネルを閉じます。これによって…(後略)

補足

2つ目のものは②に対応する解説です。この誤りは紙の書籍およびPDF版にのみ存在します。

p.74 3.3 サンプルコードの出力結果

  Sending: 0
  Sending: 1
  Sending: 2
  Sending: 3
  Producer Done.
  Received 0.
  Received 1.
  Received 2.
  Received 3.
  

  Sending: 0
  Sending: 1
  Sending: 2
  Sending: 3
  Sending: 4
  Producer Done.
  Received 0.
  Received 1.
  Received 2.
  Received 3.
  Received 4.
  

補足

原著ママ。(2018.10.28現在 原著errata未登録) GOOS=Linux GOARCH=amd64 にて、CPUコア数が1と8の状況で正の場合と同様の結果となりました。またソースコードを見ても結果が決定的なコードなので、誤りであると判断しました。(2018.10.29 ePub版、mobi版で修正済み)

c.f.

  • https://github.com/ymotongpoo/concurrency-in-go-src/blob/autotest/result-n1-standard-8-go1.11.1/fig-using-buffered-chans.go.txt
  • https://github.com/ymotongpoo/concurrency-in-go-src/blob/autotest/result-n1-standard-1/fig-using-buffered-chans.go.txt

p.76 3.3 表3-2

受信専用

読み込み専用

補足

訳語揺れでした。

p.80 3.4 2段落目

どれが用意できたを確認します

どれが用意できたかを確認します

補足

「か」が抜けていました。(2018.10.29 ePub版、mobi版で修正済み)

p.81 3.4 3段落目

内容

ご覧のとおり、1000回の繰り返しの中で、

補足

上のサンプルコードでは for i := 1000; i >= 0; i-- とあるので、正確には繰り返しは1001回。(出力結果も足すと1001になる)厳密にするかどうか、原文の文章表現の問題でもあるため、脚注として補足すべき内容。

(2018.11.14 ePub版、mobi版で対応済み)

p.81 3.4 3段落目

つまり、case分全体では

つまり、case文全体では

補足

「ぶん」の誤字でした。(2018.10.29 ePub版、mobi版で修正済み)

p.89 4.1 1段落目

これはコンパイラを駆使して拘束を矯正するというものです。

これはコンパイラを駆使して拘束を強制するというものです。

補足

「きょうせい」の誤字でした。(2018.10.29 ePub版、mobi版で修正済み)

p.104 4.6 2段落目

モナドのセブセットと考えることもできます。

モナドのサブセットと考えることもできます。

補足

「サブセット」の誤字でした。(2018.10.29 ePub版、mobi版で修正済み)

p.104 4.6 脚注5

具象化

具体化

補足

reification の訳語が不統一でした。本書では「具体化」で統一します。(2018.10.29 ePub版、mobi版で修正済み)

p.110 4.6.1 1段落目

プログラムが処理を追える前に done チャネルに対して

プログラムが処理を終える前に done チャネルに対して

補足

「おう」の誤字でした。(2018.10.29 ePub版、mobi版で修正済み)

p.144 4.12 4段落目

値も期待した方と違うかもしれません。

値も期待した型と違うかもしれません。

補足

「かた」の誤字でした。(2018.10.29 ePub版、mobi版で修正済み)

p.145 本文5行目

データの取得する

データを取得する

補足

助詞の誤りでした。

p.146 下から4行目

パラーメーター

パラメーター

補足

余分な音引きが入っていました。

p.153 3段落目

ユーザーがもっと多くの情報を得たい場合に参照するできるようにすることを忘れないでください。

ユーザーがもっと多くの情報を得たい場合に参照できるようにすることを忘れないでください。

補足

余計な「する」が入っていました。(2018.10.29 ePub版、mobi版で修正済み)

p.166 ソースコードの解説③

これによりゴルーチンからハートビートやってくるのを確認できます。

これによりゴルーチンからハートビートがやってくるのを確認できます。

補足

「が」の脱字でした。(2018.10.29 ePub版、mobi版で修正済み)

p.171 本文1行目

結果ごと1つ

結果ごとに1つ

補足

助詞「に」が脱落していました。

p.177 5.4 本文13行目

この例のような

この例のように

係り受けの関係が判別しづらいので、助詞を変更しました。

p.178-179 「現場からの声」囲み

この設計によって、複数のマシン水平にスケールアウトできました

この設計によって、複数のマシンを水平にスケールアウトできました

補足

「を」の脱字でした。(2018.10.29 ePub版、mobi版で修正済み)

p.207 6.1.1 箇条書き2行目

fib次の呼び出し

fibの次の呼び出し

補足

「の」の脱字でした。

p.209 6.1.1 2つめの表の次の行

この時点でh

この時点で

補足

余分な「h」が挿入されていました。

p.213 6.1 脚注6

「スレッドプールにスレッドを作っておくことで、スレッド起動の重いコストを払わずに、ゴルーチンがブロックされた時、即座に他のゴルーチンを起動できるようになるというものがあります。

「スレッドプールにスレッドを作っておくことで、スレッド起動の重いコストを払わずに、ゴルーチンがブロックされた時、即座に他のゴルーチンを起動できるようになる」というものがあります。

補足

鉤括弧の閉じ忘れでした。(2018.10.29 ePub版、mobi版で修正済み)

p.216 A.1 サンプルコード実行結果の解説③

自動に決められた一意の識別子が割り振られます。

自動的に決められた一意な識別子が割り振られます。

補足

「的」の脱字と「一意な」への訂正です。(2018.10.29 ePub版、mobi版で修正済み)

p.218 A.3 脚注2

net/http/pprof という標準パッケージも提供されいます。

net/http/pprof という標準パッケージも提供されています。

補足

「て」が脱字していました。(2018.10.29 ePub版、mobi版で修正済み)

p.219 A.4 下から2行目

ruuntime/traceパッケージ

runtime/traceパッケージ

補足

runtimeパッケージの綴りに誤りがありました。

正誤表(2刷)

p.2 本文下から7行目

また別の例としてπの数値計算を考えてみましょう。

また別の例として円周率πの数値計算を考えてみましょう。

補足

πに「円周率」を補いました(同ページ下から2行目も同様に「円周率πの計算」とします)。

p.19 7行目

高精度の円周率πの計算は並行処理が最もうまく使われているものの1つですが

高精度の円周率πの計算は並行処理が効率的ですが

p.19 9行目、箇条書きの1つ目

● この関数を使ってどうやってπ計算ができるのか。

● この関数を使うと並行処理になるのか。

p.38 7行目

高精度の円周率πの計算は並行処理が最もうまく使われているものの1つですが、

高精度の円周率πの計算は並行処理が効率的ですが、

p.49 3.2.1の末尾に注を追加

訳注: 並行処理なので出力結果は順不同です。紙面の例は一例です。

p.53 本文1行目

読み込みの数が 213になってようやく生まれます。

読み込みの数が 2^13になってようやく生まれます。

補足

累乗の表記に誤りがありました、紙面は13が肩つきの表記になります。また、この行の末尾に以下の注を追加します。

訳注: 原書では「2^13」と記載されていますが、出力結果を見ると2^18で逆転しています。

p.55 箇条書き❾の冒頭

❾ スライスと先頭をスライスの2番めの要素を指すように変えることで

❾ スライスの先頭をスライスの2番めの要素を指すように変えることで

補足

「スライスの先頭」が「スライスと先頭」になっておりました。

p.57 下から7行目に訳注を追加

訳注: このコードはこのままでは c.Wait()button.Clicked.Broadcast() で待つかどうかの保証がないため、期待した動作をしない可能性があります。また button.Clicked.Broadcast() を何度も呼べるようにする場合には subscribe が必要分事前に呼ばれている必要があることに注意してください。

p.61 下から7行目

アロケート済みのオブジェクトを暖気する状況です。

アロケート済みのオブジェクトを暖機する状況です。

補足

エンジンなどを低負荷状態でしばらく動かすのは「暖機運転」で、「暖気」は「暖機」とつづるべきでした。

p.68 3.2.1の末尾に訳注を追加

訳注: 並行処理なので出力結果は順不同です。紙面の例は一例です。

p.101 本文の下から6行目の末尾から

広い視点で見れば、エラーハンドリングの懸念と生産者のゴルーチンを無事に切り分けられたということです。

広い視点で見れば、エラーハンドリングの懸念を生産者のゴルーチンから無事に切り分けられたということです。

p.114 1行目末尾

関心事はリストをや処理を繰り返してデータのストリームを生成することです

関心事はリストや処理を繰り返してデータのストリームを生成することです

補足

「リストや」が「リストをや」となっていました。

p.147 ③の説明

複雑なパッケージのインポート関係を必要としなれば、

複雑なパッケージのインポート関係を必要としなければ、

補足

「必要としなければ」の「け」が脱落していました。

目次

訳者まえがき
序文

1章 並行処理入門
    1.1 ムーアの法則、Webスケール、そして私たちのいる混沌
    1.2 なぜ並行処理が難しいのか
        1.2.1 競合状態
        1.2.2 アトミック性
        1.2.3 メモリアクセス同期
        1.2.4 デッドロック、ライブロック、リソース枯渇
        1.2.5 並行処理の安全性を見極める
    1.3 複雑さを前にした簡潔さ

2章 並行性をどうモデル化するか:CSPとは何か
    2.1 並行性と並列性の違い
    2.2 CSPとは何か
    2.3 これがどう役に立つのか
    2.4 Goの並行処理における哲学

3章 Goにおける並行処理の構成要素
    3.1 ゴルーチン(goroutine)
    3.2 syncパッケージ
        3.2.1 WaitGroup
        3.2.2 MutexとRWMutex
        3.2.3 Cond
        3.2.4 Once
        3.2.5 Pool
    3.3 チャネル(channel)
    3.4 select文
    3.5 GOMAXPROCSレバー
    3.6 まとめ

4章 Goでの並行処理パターン
    4.1 拘束
    4.2 for-selectループ
    4.3 ゴルーチンリークを避ける
    4.4 orチャネル
    4.5 エラーハンドリング
    4.6 パイプライン
        4.6.1 パイプライン構築のためのベストプラクティス
        4.6.2 便利なジェネレーターをいくつか
    4.7 ファンアウト、ファンイン
    4.8 or-doneチャネル
    4.9 teeチャネル
    4.10 bridgeチャネル
    4.11 キュー
    4.12 contextパッケージ
    4.13 まとめ

5章 大規模開発での並行処理
    5.1 エラー伝播
    5.2 タイムアウトとキャンセル処理
    5.3 ハートビート
    5.4 複製されたリクエスト
    5.5 流量制限
    5.6 不健全なゴルーチンを直す
    5.7 まとめ

6章 ゴルーチンとGoランタイム
    6.1 ワークスティーリング
        6.1.1 タスクと継続、どちらを盗むのか
    6.2 すべての開発者にこの言葉を贈ります
    6.3 結論

補遺A    
    A.1 ゴルーチンのエラーの解剖
    A.2 競合状態の検出
    A.3 pprof
    A.4 trace

補遺B go generate
    B.1 空インターフェースの使用について
    B.2 go generateとは何か
    B.3 go generate の機能
    B.4 例: genny を利用する
    B.5 ジェネリクスについて

著者紹介