Skip to content

Commit

Permalink
GLOBAL_DEFINED_WORDS: よりも前に発生する (happens before) / と同期する (synchronize…
Browse files Browse the repository at this point in the history
…s with) を追加
  • Loading branch information
akinomyoga committed Nov 7, 2024
1 parent ca64b9a commit 026aee8
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 13 deletions.
12 changes: 12 additions & 0 deletions GLOBAL_DEFINED_WORDS.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,17 @@
},
"オーバーロード解決": {
"desc": "関数呼び出し時に、同名の関数の中から実際に呼び出す関数を決定する処理。このときの候補になることを、オーバーロード解決に参加するという"
},
"と同期する": {
"yomi": "とどうきする",
"desc": "synchronizes with。「A は B と同期する」という記述は「A が B よりも前に発生する」関係を保証する"
},
"よりも前に発生する": {
"yomi": "よりもまえにはっせいする",
"desc": "happens before。(異なるスレッド間の) 2つの操作の実行順序を規定する関係"
},
"よりも確実に前に発生する": {
"yomi": "よりもかくじつにまえにはっせいする",
"desc": "strongly happens before。(異なるスレッド間の) 2つの操作の実行順序を規定する強い関係"
}
}
6 changes: 3 additions & 3 deletions reference/atomic/memory_order.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace std {
## 概要
コンパイラに許可されている最適化の一つに、「プログラムの意味を変えない限りにおいて、メモリアクセスの順番を変えたり、省略したりしてもよい」というものがある。また、マルチコアCPUにおいては、あるCPUコアによるメモリアクセスの順序が他のコアからも同じように見えるとは限らない。このような挙動はマルチスレッドプログラミングにおいて問題になることがある。
この問題への対処として、C++11では各スレッドの実行に順序付けをするための"happens before"(先行発生)という関係を定義し、それによってあるスレッドでの操作が他スレッドから可視になるか否かを定めている。
この問題への対処として、C++11では各スレッドの実行に順序付けをするための「よりも前に発生する」という関係を定義し、それによってあるスレッドでの操作が他スレッドから可視になるか否かを定めている。
atomic変数においては、"release"操作によって書き込まれた値を"acquire"操作によって別のスレッドが読み出した場合に、そのrelease操作とacquire操作の間に順序付けが行われる。以下に例を挙げる。
```cpp example
Expand Down Expand Up @@ -65,8 +65,8 @@ int main()
3
```

[`atomic<bool>`](atomic.md)型の変数`ready`への読み書きに注目すると、`main()`では変数`ready`に `true` を"release"操作として書き込み、`f()`では"acquire"操作としての読み込みを `true` が返されるまで繰り返している。よって、`f()`の`while`ループを抜けた時点で、`main()`の`ready.store()`と`f()`の`ready.load()`の間に順序付け(happens before関係)が成立している。
ここでさらに変数`data`への読み書き(1), (2)に注目すると、(1)は`ready.store()`より前、(2)は`ready.load()`より後にあるので、以下のようなスレッド間の順序付け(happens before関係)が成立することになる。
[`atomic<bool>`](atomic.md)型の変数`ready`への読み書きに注目すると、`main()`では変数`ready`に `true` を"release"操作として書き込み、`f()`では"acquire"操作としての読み込みを `true` が返されるまで繰り返している。よって、`f()`の`while`ループを抜けた時点で、`main()`の`ready.store()`と`f()`の`ready.load()`の間に順序付け(「よりも前に発生する」関係)が成立している。
ここでさらに変数`data`への読み書き(1), (2)に注目すると、(1)は`ready.store()`より前、(2)は`ready.load()`より後にあるので、以下のようなスレッド間の順序付け(「よりも前に発生する」関係)が成立することになる。
(1) → `ready.store()` → `ready.load()` → (2)
よって、(1)における書き込みが(2)の時点で可視であることが保証される。
このようにしてC++のマルチスレッドプログラムにおける実行順序および可視性を理解することができる。
Expand Down
2 changes: 1 addition & 1 deletion reference/barrier/barrier.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace std {
- 完了関数を呼び出す。`completion()`と等価。
- フェーズ同期ポイント上でブロックされている全スレッドのブロックを解除する。
完了ステップの終了は、完了ステップによりブロック解除される全ての関数呼び出しからの復帰よりも、確実に前に発生(strongly happens before)する
完了ステップの終了は、完了ステップによりブロック解除される全ての関数呼び出しからの復帰**よりも確実に前に発生する**
テンプレートパラメータ`CompletionFunction`のデフォルト値以外の特殊化においては、完了ステップの進行中にバリアオブジェクトの[`wait()`](barrier/wait.md)を除くメンバ関数が呼び出されると、その動作は未定義となる。
テンプレートパラメータ`CompletionFunction`のデフォルト値は、追加で Cpp17DefaultConstructible 要件を満たす未規定の型であり、式`completion()`は何の副作用も生じない。
Expand Down
4 changes: 2 additions & 2 deletions reference/syncstream/basic_syncbuf/emit.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ bool emit();


## 同期
同じストリームバッファオブジェクトに文字を転送するすべての`emit()`呼び出しは、「happens before」関係と一致する全順序で実行されるように見える。各`emit()`呼び出しは、その全順序で後続の`emit()`呼び出しと同期する。実際には、これは下記の備考にあることを意味する。
同じストリームバッファオブジェクトに文字を転送するすべての`emit()`呼び出しは、「よりも前に発生する」関係と一致する全順序で実行されるように見える。各`emit()`呼び出しは、その全順序で後続の`emit()`呼び出し**と同期する**。実際には、これは下記の備考にあることを意味する。

注:ここでは、happens before 関係は全順序関係になっていると考えられる。また、modification order と矛盾しないとも考えられる。下記の参照を参照のこと。
注:ここでは、「よりも前に発生する」関係は全順序関係になっていると考えられる。また、modification order と矛盾しないとも考えられる。下記の参照を参照のこと。

## 備考
ラップされたストリームに一意に関連付けられたロックを保持しながら、ラップされたストリームのメンバ関数を呼び出すことができる。つまり、同じストリームを持つ他の`basic_syncbuf`オブジェクトに対してアトミックに転送することができる。
Expand Down
4 changes: 2 additions & 2 deletions reference/thread/jthread/join.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ void join();


## 同期
関連付けられたスレッドの完了は、`join()`メンバ関数の正常リターンと **同期する**
関連付けられたスレッドの完了は、`join()`メンバ関数の正常リターン**と同期する**

つまり、「`this`に関連付けられたスレッドT1上で行われる全処理の完了」は、
`join()`メンバ関数を呼び出したスレッドT0上での同メンバ関数からの正常リターン」よりも **前に発生する**
`join()`メンバ関数を呼び出したスレッドT0上での同メンバ関数からの正常リターン」**よりも前に発生する**


## 事後条件
Expand Down
4 changes: 2 additions & 2 deletions reference/thread/jthread/op_constructor.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ jthread(jthread&&) noexcept; // (4) C++20
## 同期
- (2) : コンストラクタ呼び出しの完了は、`f`のコピーの呼び出し開始と同期する
- (2) : コンストラクタ呼び出しの完了は、`f`のコピーの呼び出し開始**と同期する**
新しいスレッドを生成し、[`INVOKE`](/reference/concepts/Invoke.md)`(DECAY_COPY(`[`std::forward`](/reference/utility/forward.md)`<F>(f)), DECAY_COPY(`[`std::forward`](/reference/utility/forward.md)`<Args>(args))...)`を実行する。ただし`DECAY_COPY`は同コンストラクタを呼び出したスレッド上にて評価される。また`f`のコピーの戻り値は無視される。
- `DECAY_COPY(x)`は `template <class T> typename std::decay<T>::type decay_copy(T&& v) { return` [`std::forward`](/reference/utility/forward.md)`<T>(v); }` と定義される。おおよそ、`x`が配列型なら先頭要素へのポインタ、`x`が関数型ならその関数ポインタ、`x`がコピーコンストラクト可能な型なら`x`からコピーされたオブジェクト、`x`がムーブコンストラクト可能な型なら`x`からムーブされたオブジェクトとなる。
## 同期
- (2) : 同コンストラクタの呼び出し完了は、fのコピーの呼び出し開始と**同期する**。つまり、「コンストラクタ呼び出し側スレッドT0でのコンストラクタ呼び出し完了」は、「新しいスレッド`T1`上での`f`のコピーの呼び出し開始」よりも**前に発生する**。
- (2) : 同コンストラクタの呼び出し完了は、fのコピーの呼び出し開始**と同期する**。つまり、「コンストラクタ呼び出し側スレッドT0でのコンストラクタ呼び出し完了」は、「新しいスレッド`T1`上での`f`のコピーの呼び出し開始」**よりも前に発生する**。
## 事後条件
Expand Down
4 changes: 2 additions & 2 deletions reference/thread/thread/join.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ void join();


## 同期
関連付けられたスレッドの完了は、`join()`メンバ関数の正常リターンと **同期する**
関連付けられたスレッドの完了は、`join()`メンバ関数の正常リターン**と同期する**

つまり、「`this`に関連付けられたスレッドT1上で行われる全処理の完了」は、
`join()`メンバ関数を呼び出したスレッドT0上での同メンバ関数からの正常リターン」よりも **前に発生する**
`join()`メンバ関数を呼び出したスレッドT0上での同メンバ関数からの正常リターン」**よりも前に発生する**


## 事後条件
Expand Down
2 changes: 1 addition & 1 deletion reference/thread/thread/op_constructor.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ thread(thread&&) noexcept; // (4)
## 同期
- (2) : 同コンストラクタの呼び出し完了は、fのコピーの呼び出し開始と**同期する**。つまり、「コンストラクタ呼び出し側スレッドT0でのコンストラクタ呼び出し完了」は、「新しいスレッド`T1`上での`f`のコピーの呼び出し開始」よりも**前に発生する**。
- (2) : 同コンストラクタの呼び出し完了は、fのコピーの呼び出し開始**と同期する**。つまり、「コンストラクタ呼び出し側スレッドT0でのコンストラクタ呼び出し完了」は、「新しいスレッド`T1`上での`f`のコピーの呼び出し開始」**よりも前に発生する**。
## 事後条件
Expand Down

0 comments on commit 026aee8

Please sign in to comment.