Skip to content

Commit e782adf

Browse files
committed
update concurrency
1 parent e4e0ae0 commit e782adf

File tree

3 files changed

+102
-269
lines changed

3 files changed

+102
-269
lines changed

1.9/ja/book/concurrency.md

Lines changed: 100 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -274,30 +274,68 @@ Rustはこれが安全でないだろうと知っているのです!
274274
<!-- of the number of references to it, hence the "reference count" part of its name. -->
275275
そのため、1つの値に対して2つ以上の所有権を持った参照を持てるような型が必要です。
276276
通常、この用途には `Rc<T>` を使います。これは所有権の共有を提供するリファレンスカウントの型です。
277-
実行時のなんちゃらがひつようで、リファレンスの数をカウントします。なのでリファレンスカウントです
277+
実行時にある程度の管理コストを払って、値への参照の数をカウントします。なのでリファレンスカウントなのです
278278

279-
<!-- So, we need some type that lets us have more than one reference to a value and -->
280-
<!-- that we can share between threads, that is it must implement `Sync`. -->
281-
そのため、1つの値に対して2つ以上の参照を持てるようにして、スレッド間で共有できるような型が必要です
282-
そして、その型は `Sync` を実装していなければなりません。
279+
<!-- Calling `clone()` on an `Rc<T>` will return a new owned reference and bump the -->
280+
<!-- internal reference count. We create one of these for each thread: -->
281+
`Rc<T>` に対して `clone()` を呼ぶと新たな所有権を持った参照を返し、内部の参照カウント数を増やします
282+
スレッドそれぞれで `clone()` を取ります:
283283

284-
<!-- We'll use `Arc<T>`, Rust's standard atomic reference count type, which -->
285-
<!-- wraps a value up with some extra runtime bookkeeping which allows us to -->
286-
<!-- share the ownership of the value between multiple references at the same time. -->
287-
Rustの標準アトミック参照カウント型である `Arc<T>` を使いましょう。
288-
これは複数の参照間で値の所有権を同時に共有できるように、値を特別な実行時の管理用データでくるむものです。
284+
```ignore
285+
use std::thread;
286+
use std::time::Duration;
287+
use std::rc::Rc;
288+
289+
fn main() {
290+
let mut data = Rc::new(vec![1, 2, 3]);
291+
292+
for i in 0..3 {
293+
# // create a new owned reference
294+
// 所有権を持った参照を新たに作る
295+
let data_ref = data.clone();
289296
290-
<!-- The bookkeeping consists of a count of how many of these references exist to -->
291-
<!-- the value, hence the reference count part of the name. -->
292-
その管理用データには、値への参照がいくつ存在しているかというカウントが記録されています。
293-
すなわち名前の「参照カウント」の部分にあたります。
297+
# // use it in a thread
298+
// スレッド内でそれを使う
299+
thread::spawn(move || {
300+
data_ref[i] += 1;
301+
});
302+
}
303+
304+
thread::sleep(Duration::from_millis(50));
305+
}
306+
```
307+
308+
<!-- This won't work, however, and will give us the error: -->
309+
これは動作せず、以下のようなエラーを出します:
310+
311+
```text
312+
13:9: 13:22 error: the trait bound `alloc::rc::Rc<collections::vec::Vec<i32>> : core::marker::Send`
313+
is not satisfied
314+
...
315+
13:9: 13:22 note: `alloc::rc::Rc<collections::vec::Vec<i32>>`
316+
cannot be sent between threads safely
317+
```
318+
319+
<!-- As the error message mentions, `Rc` cannot be sent between threads safely. This -->
320+
<!-- is because the internal reference count is not maintained in a thread safe -->
321+
<!-- matter and can have a data race. -->
322+
エラーメッセージで言及があるように、 `Rc` は安全に別のスレッドに送ることが出来ません。
323+
これは内部の参照カウントがスレッドセーフに管理されていないのでデータ競合を起こし得るからです。
324+
325+
<!-- To solve this, we'll use `Arc<T>`, Rust's standard atomic reference count type. -->
326+
この問題を解決するために、 `Arc<T>` を使います。Rustの標準のアトミックなリファレンスカウント型です。
294327

295328
<!-- The Atomic part means `Arc<T>` can safely be accessed from multiple threads. -->
296329
<!-- To do this the compiler guarantees that mutations of the internal count use -->
297330
<!-- indivisible operations which can't have data races. -->
298331
「アトミック」という部分は `Arc<T>` が複数スレッドから安全にアクセスできることを意味しています。
299332
このためにコンパイラは、内部のカウントの更新には、データ競合が起こりえない分割不能な操作が用いられることを保証します。
300333

334+
335+
<!-- In essence, `Arc<T>` is a type that lets us share ownership of data _across -->
336+
<!-- threads_. -->
337+
要点は `Arc<T>`_スレッド間_ で所有権を共有可能にする方ということです。
338+
301339
```ignore
302340
use std::thread;
303341
use std::sync::Arc;
@@ -317,9 +355,9 @@ fn main() {
317355
}
318356
```
319357

320-
<!-- We now call `clone()` on our `Arc<T>`, which increases the internal count. -->
358+
<!-- Similarly to last time, we use `clone()` to create a new owned handle. -->
321359
<!-- This handle is then moved into the new thread. -->
322-
ここで `Arc<T>` について `clone()` を呼んで、内部のカウントを増やしています
360+
前回と同様に `clone()` を使って所有権を持った新たなハンドルを作っています
323361
そして、このハンドルは新たなスレッドに移動されます。
324362

325363
<!-- And... still gives us an error. -->
@@ -332,20 +370,26 @@ fn main() {
332370
^~~~
333371
```
334372

335-
<!-- `Arc<T>` assumes one more property about its contents to ensure that it is safe -->
336-
<!-- to share across threads: it assumes its contents are `Sync`. This is true for -->
337-
<!-- our value if it's immutable, but we want to be able to mutate it, so we need -->
338-
<!-- something else to persuade the borrow checker we know what we're doing. -->
339-
`Arc<T>` はスレッドをまたいだ共有を安全にするために、その中身に対してもう一つの仮定をおいています。
340-
それは、中身が `Sync` であるという仮定です。
341-
この仮定は値がイミュータブルであるときは真になりますが、今回は値を変化できるようにしたいです。
342-
そのため、借用チェッカに対し、我々は自分たちが何をやっているかを知っています、と説得するための何かが必要になります。
343-
344-
<!-- It looks like we need some type that allows us to safely mutate a shared value, -->
345-
<!-- for example a type that can ensure only one thread at a time is able to -->
346-
<!-- mutate the value inside it at any one time. -->
347-
共有された値を安全に変更できるようにするための型が必要そうです。
348-
例えば、どの時点においても、同時に一つのスレッドのなかでしか値は変更できないということを保証できる型です。
373+
<!-- `Arc<T>` by default has immutable contents. It allows the _sharing_ of data -->
374+
<!-- between threads, but shared mutable data is unsafe and when threads are -->
375+
<!-- involved can cause data races! -->
376+
`Arc<T>` が保持する値はデフォルトでイミュータブルです。
377+
スレッド間での _共有_ はしてくれますがスレッドが絡んだ時の共有されたミュータブルなデータはデータ競合を引き起こし得ます。
378+
379+
<!-- Usually when we wish to make something in an immutable position mutable, we use -->
380+
<!-- `Cell<T>` or `RefCell<T>` which allow safe mutation via runtime checks or -->
381+
<!-- otherwise (see also: [Choosing Your Guarantees](choosing-your-guarantees.html)). -->
382+
<!-- However, similar to `Rc`, these are not thread safe. If we try using these, we -->
383+
<!-- will get an error about these types not being `Sync`, and the code will fail to -->
384+
<!-- compile. -->
385+
通常イミュータブルな位置のものをミュータブルにしたい時は `Cell<T>` 又は `RefCell<T>` が実行時のチェックあるいは他の方法で安全に変更する手段を提供してくれる(参考: [保障を選ぶ](choosing-your-guarantees.html))のでそれを使います。
386+
しかしながら `Rc` と同じくこれらはスレッドセーフではありません。
387+
これらを使おうとすると `Sync` でない旨のエラーが出てコンパイルに失敗します。
388+
389+
<!-- It looks like we need some type that allows us to safely mutate a shared value -->
390+
<!-- across threads, for example a type that can ensure only one thread at a time is -->
391+
<!-- able to mutate the value inside it at any one time. -->
392+
スレッド間で共有された値を安全に変更出来る型、例えばどの瞬間でも同時に1スレッドしか内容の値を変更できないことを保障する型が必要そうです。
349393

350394
<!-- For that, we can use the `Mutex<T>` type! -->
351395
そのためには、 `Mutex<T>` 型を使うことができます!
@@ -377,9 +421,24 @@ fn main() {
377421
among the threads. -->
378422
`i` の値はクロージャへ束縛(コピー)されるだけで、スレッド間で共有されるわけではないことに注意してください。
379423

380-
<!-- Also note that [`lock`](../std/sync/struct.Mutex.html#method.lock) method of -->
424+
<!-- We're "locking" the mutex here. A mutex (short for "mutual exclusion"), as -->
425+
<!-- mentioned, only allows one thread at a time to access a value. When we wish to -->
426+
<!-- access the value, we use `lock()` on it. This will "lock" the mutex, and no -->
427+
<!-- other thread will be able to lock it (and hence, do anything with the value) -->
428+
<!-- until we're done with it. If a thread attempts to lock a mutex which is already -->
429+
<!-- locked, it will wait until the other thread releases the lock. -->
430+
ここではmutexを「ロック」しているのです。
431+
mutex(「mutual exclusion(訳注: 相互排他)」の略)は前述の通り同時に1つのスレッドからのアクセスしか許しません。
432+
値にアクセスしようと思ったら、 `lock()` を使います。これは値を使い終わるまでmutexを「ロック」して他のどのスレッドもロック出来ない(そして値に対して何も出来ない)ようにします。
433+
もし既にロックされているmutexをロックしようとすると別のスレッドがロックを解放するまで待ちます。
434+
435+
<!-- The lock "release" here is implicit; when the result of the lock (in this case, -->
436+
<!-- `data`) goes out of scope, the lock is automatically released. -->
437+
ここでの「解放」は暗黙的です。ロックの結果(この場合は `data`)がスコープを出ると、ロックは自動で解放されます
438+
439+
<!-- Note that [`lock`](../std/sync/struct.Mutex.html#method.lock) method of -->
381440
<!-- [`Mutex`](../std/sync/struct.Mutex.html) has this signature: -->
382-
また、[`Mutex`](../std/sync/struct.Mutex.html)[`lock`](../std/sync/struct.Mutex.html#method.lock) メソッドは以下のシグネチャを持つことにも注意してください
441+
[`Mutex`](../std/sync/struct.Mutex.html)[`lock`](../std/sync/struct.Mutex.html#method.lock)メソッドは次のシグネチャを持つことを気をつけて下さい
383442

384443
```ignore
385444
fn lock(&self) -> LockResult<MutexGuard<T>>
@@ -410,7 +469,7 @@ thread::spawn(move || {
410469
```
411470

412471
<!-- First, we call `lock()`, which acquires the mutex's lock. Because this may fail, -->
413-
<!-- it returns an `Result<T, E>`, and because this is just an example, we `unwrap()` -->
472+
<!-- it returns a `Result<T, E>`, and because this is just an example, we `unwrap()` -->
414473
<!-- it to get a reference to the data. Real code would have more robust error handling -->
415474
<!-- here. We're then free to mutate it, since we have the lock. -->
416475
まず、 `lock()` を呼び、mutex のロックを獲得します。
@@ -451,6 +510,10 @@ use std::sync::mpsc;
451510
fn main() {
452511
let data = Arc::new(Mutex::new(0));
453512

513+
# // `tx` is the "transmitter" or "sender"
514+
# // `rx` is the "receiver"
515+
// `tx` は送信(transmitter)
516+
// `rx` は受信(receiver)
454517
let (tx, rx) = mpsc::channel();
455518

456519
for _ in 0..10 {
@@ -470,14 +533,14 @@ fn main() {
470533
}
471534
```
472535

473-
<!-- We use the `mpsc::channel()` method to construct a new channel. We just `send` -->
536+
<!-- We use the `mpsc::channel()` method to construct a new channel. We `send` -->
474537
<!-- a simple `()` down the channel, and then wait for ten of them to come back. -->
475538
`mpsc::channel()` メソッドを使って、新たなチャネルを生成しています。
476-
そして、ただの `()` をチャネルを通じて単に `send` し、それが10個戻ってくるのを待機します。
539+
そして、ただの `()` をチャネルを通じて `send` し、それが10個戻ってくるのを待機します。
477540

478-
<!-- While this channel is just sending a generic signal, we can send any data that -->
541+
<!-- While this channel is sending a generic signal, we can send any data that -->
479542
<!-- is `Send` over the channel! -->
480-
このチャネルはただシグナルを送っているだけですが`Send` であるデータならばなんでもこのチャネルを通じて送れます!
543+
このチャネルはシグナルを送っているだけですが`Send` であるデータならばなんでもこのチャネルを通じて送れます!
481544

482545
```rust
483546
use std::thread;

TranslationTable.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@
115115
| lifetime parameter | ライフタイムパラメータ
116116
| link | リンク
117117
| lint | リント
118+
| lock | ロック
118119
| mangling | マングリング
119120
| match | マッチ
120121
| memory | メモリ
@@ -133,6 +134,7 @@
133134
| option | オプション
134135
| output lifetime | 出力ライフタイム
135136
| overflow | オーバーフロー
137+
| owned | 所有権を持った
136138
| owner | 所有者
137139
| ownership | 所有権
138140
| panic | パニック

0 commit comments

Comments
 (0)