下記の誤りがありました。お詫びして訂正いたします。
本ページに掲載されていない誤植など間違いを見つけた方は、japan@oreilly.co.jpまで お知らせください。pull requestでも報告いただけます。
頁 | 誤 | 正 |
---|---|---|
2章。P.30。最後の行。 | Gender型とほぼ同じあるが | Sex型とほぼ同じであるが |
3章。P.65。❷の3行目。 | 代入してして | 代入して |
3章。P.67。3.3.1の1行目。 | 繰り返していていたが、 | 繰り返していたが、 |
3章。P.96。❶。 | ミューテックスと状態変数 | ミューテックスと条件変数 |
4章。P.131。4.7から3行目。 | IPC : instructions per second | IPS : instructions per second |
4章。P.131。4.7から8行目。 | IPC | IPS |
4章。P.132。2文目。 | ロック用命令よりも前に実行さてしまったとすると、 | ロック用命令よりも前に実行されてしまったとすると、 |
4章。P.134。表4-4。x86-64およびRISC-V (TSO)。 | R→Wに✓ | W→Rに✓ |
4章。P.134。8行目。 | R→Wの順についてのみリオーダリングが行われる | W→Rの順についてのみリオーダリングが行われる |
4章。P.134。表4-5。6行目。およびページ最終行。 | SecCst |
SeqCst |
5章。P.157。下から7行目。 | unistd::write, |
unistd::{read, write}, |
5章。P.158。5.3.2.1の直前。 | 本実装ではこの関数を利用して eventfd に 1 を書き込むことで IOSelector へ通知し、IOSelector は読み込み後に 0 を書き込むことでイベント通知を解除する。 | 本実装ではこの関数を利用して eventfd に 1 を書き込み IOSelector へ通知し、IOSelector は eventfd を読み込みイベント通知を解除する。 |
5章。P.161。 | この表の下にある説明を参照してください | |
6章。P.190。ソースコード右上の言語指定。 | ASM x86-64 | ASM AArch64 |
6章。P.198。下から3行目。 | src/context.S で示されるように |
Registers 型の値を生成する new 関数の定義で示されるように |
6章。P.203。5行目下の出力例 | Orgega! |
Ortega! |
7章。P.218。7.1.2の直前の行。 | 指定しなければならい。 | 指定しなければならない。 |
7章。P.227。7.2.1から4行目。 | 重要な特徴な | 重要な特徴は |
8章。P.291。式中8行目。 | ▶ send(n2, b) ◀︎ |
▶ send(n3, b) ◀︎ |
8章。P.294。5行目。 | recvSync | syncRecv |
8章。P.294。8.4より4行目。 | 非同期的のπ計算は | 非同期的なπ計算は |
8章。P.298。3つ目の式中。 | ( P2.P.3) | (P2.P3) |
8章。P.302。上から2行目 | (P | Q) ≡ P | (Q | P) | (P | Q) | R ≡ P | (Q | R) |
8章。P.302。真ん中の証明。 | 3. c̅x + 0 | 3. c̅x.0 + 0 |
8章。P.302。真ん中の証明。 | ステップ2は不要 | 2を削除し、ステップ3での2の要請も不要 |
8章。P.304。8.4.6の上の行。 | MATCH規則、MISMATCH規則、RES規則はそのままの意味であるため説明は割愛する。 | この文章は削除 |
付録A。P.336。表A-18。4行目。 | dst = src1 - src2 × src3 | dst = src3 - src1 × src2 |
以下の2行が追加必要です。
let mut buf: [u8; 8] = [0; 8];
read(self.event, &mut buf).unwrap(); // eventfdの通知解除
conc_ytakano/chap5/5.3/ch5_3_2_ioselect/src/main.rs
Lines 146 to 147 in 1d2fcb0
「アクターモデル」の章の「バリア同期」の式が誤っていました。下記ページに修正版を掲載しています。
https://oreilly-japan.github.io/conc_ytakano/barrier.html
ISO 5218によると、ヒトの身体的性別はGenderではなく、Sexとするのが正しい表記となります。 本文中のGenderはSexの誤りとなります。また、enumの定義は、正しくは以下となります。
enum Sex {
Unknown,
Male,
Female,
NotApplicable
}
def hello():
print('Hello,', end='')
yield # ここで中断、再開 (1)
print('World!')
yield # ここまで実行 (2)
h = hello() # イテレータを生成
h.__next__() # 1まで実行し中断
h.__next__() # 1から再開し2まで実行
本文やソースコードに複数登場する「aqcuire」は「acquire」のスペルミスとなります。
8章の複数箇所で、「関数fに対して、引数aを適用する」といった形式の記述がありますが、 これらはすべて、「引数aに対して、関数fを適用する」が正しい記述となります。
具体的な修正箇所は以下となります。
頁 | 誤 | 正 |
---|---|---|
P.266。3段落目。3行目。 | λx.Mというλ式に値aを適用することは | 値aにλx.Mというλ式を適用することは |
P.266。4段落目。1行目。 | λx.x^2に数字の3を適用 | 数字の3にλx.x^2を適用 |
P.266。下から1行目。 | この式に値、3, 4を適用 | 値3, 4にこの式を適用 |
P.267。3行目。 | λ式に3を適用した段階 | 3にλ式を適用した段階 |
P.267。8行目。 | これに数字の2のみを適用 | 数字の2のみにこれを適用 |
P.267。9行目。 | この式に2を適用したものをF | 2にこの式を適用したものをF |
P.267。12行目。 | 一部の引数のみに値を適用することを | 一部の引数のみに式を適用することを |
P.268。2行目。 | 値3と、2乗する関数を、この式に適用すると | 値3と、2乗する関数に、この式を適用すると |
P.277。8.2.9.1から4行目。 | (Y g) に定数 a を適用すると | 定数aに(Y g)を適用すると |
P.278。8.2.9.3から3行目。 | 4を適用すると | 4に適用すると |
P.279。1行目。 | 上式に定数 a を引数にして適用してみると | 上式を定数 a に適用してみると |
P.328の下から5行目で次のような記述がありますが、表が記載されていませんでした。
ここで例として、符号なしの比較命令を考えてみると、比較命令実行後はオペランドの値により、ゼロフラグ(Z)とキャリーフラグ(C)は次の表のように変化する。
下記の表が正しい表となります。
cmp a, b
後の条件フラグ
Z | C | |
---|---|---|
a < b | 0 | 1 |
a > b | 0 | 0 |
a = b | 1 | 0 |
一部ePub版のソースコードでは、文字列をシングルクオーテーションで囲っているように表示されますが、ダブルクォーテーションとなります。 ファイルでは、ダブルクォーテーションとなっていますが、表示がシングルクォーテーションとなるようです。
// 正しいコード例
printf("id = %d, i = %d\n", id, i);
// 誤ったコード例
printf('id = %d, i = %d\n', id, i);
FirefoxのePubリーダを利用している方はご注意ください。 https://addons.mozilla.org/ja/firefox/addon/epubreader/
3.7.3 実行速度計測の図がモノクロで見難いため、カラー版を掲載いたします。
パン屋のアルゴリズムの説明が少し足りないので、追加で説明します。
パン屋のアルゴリズムは、アトミック命令を使わずにN個のスレッド間でMutexを実現するアルゴリズムとなります。 ただし、Nは固定で動的に変化しません。
P.102で定義するentering
と、ticket
ですが、これはそれぞれ、i番目のスレッドがチケットを取得中であるかと、
i番目のスレッドのチケットを保存する配列となります。
ですので、P.102冒頭で定義しているBakerlyLock
構造体には、以下のようなコメントがあるほうがよいでしょう。
// パン屋のアルゴリズム用の型 ❹
struct BakeryLock {
entering: [bool; NUM_THREADS], // i番目のスレッドがチケットを取得中であるなら、entering[i]はtrue
tickets: [Option<u64>; NUM_THREADS], // i番目のスレッドのチケットがtikect[i]
}
自身のスレッド番号をiとしたとき、そのスレッドiがロック獲得するには、 チケット獲得と他のスレッドの処理終了待機の2つを行います。
まず、以下のようにチケットを獲得します。
entering[i] = true
として、チケットを取得中であると設定tickets[i]
からチケット番号の最大値を取得- 2で得た最大値 + 1を自分のチケット番号として、
tickets[i]
に設定 entering[i] = false
と設定
その後、以下のようにして、自分以外の他のスレッドj(0からNUM_THREADS-1、ただしi以外)の処理が終了するのを待機します。 具体的には以下のように待機します。
entering[j] == false
となるまでループで待機。つまり、他のスレッドがチケットを取得中なら待機。ticket[j]
の値が自分のチケット番号より小さい、もしくはチケット番号が同じでありかつ自分のスレッド番号の方がjより小さい場合はループで待機。
この2つの処理が終了するとロック獲得となり、これを行っているのが、3.9で示したlock
関数のコードとなります。
銀行家のアルゴリズムの本来のアルゴリズムは、必要なリソース数を指定可能です。 しかし、本書で示した実装では、必要なリソース数を1と定数値としています。 issue51で、リソース数を指定可能に修正したパッチを頂きましたので、 banker_rs.v2に、 修正版をアップロードしました。
パッチを作成して頂いた方および、読書会に参加して頂いた皆様に感謝します。
再帰ロックのアルゴリズムで、lock->id
の読み書きをアトミックに行った方が良いと指摘があました。
AArch64とx86-64でLLVMかGCCを利用していると問題はないとは思われます。
一方、C言語の規格から考えると、lock->id
はアトミックとした方が良いとの指摘です。
修正後のソースコードは次のURLから確認してください。 https://github.com/oreilly-japan/conc_ytakano/blob/main/chap4/4.4/ch4_4_reent_c/reent.c
また、本件に関するissueは次のURLとなります。#61