@@ -274,30 +274,68 @@ Rustはこれが安全でないだろうと知っているのです!
274
274
<!-- of the number of references to it, hence the "reference count" part of its name. -->
275
275
そのため、1つの値に対して2つ以上の所有権を持った参照を持てるような型が必要です。
276
276
通常、この用途には ` Rc<T> ` を使います。これは所有権の共有を提供するリファレンスカウントの型です。
277
- 実行時のなんちゃらがひつようで、リファレンスの数をカウントします。なのでリファレンスカウントです 。
277
+ 実行時にある程度の管理コストを払って、値への参照の数をカウントします。なのでリファレンスカウントなのです 。
278
278
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() ` を取ります:
283
283
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();
289
296
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の標準のアトミックなリファレンスカウント型です。
294
327
295
328
<!-- The Atomic part means `Arc<T>` can safely be accessed from multiple threads. -->
296
329
<!-- To do this the compiler guarantees that mutations of the internal count use -->
297
330
<!-- indivisible operations which can't have data races. -->
298
331
「アトミック」という部分は ` Arc<T> ` が複数スレッドから安全にアクセスできることを意味しています。
299
332
このためにコンパイラは、内部のカウントの更新には、データ競合が起こりえない分割不能な操作が用いられることを保証します。
300
333
334
+
335
+ <!-- In essence, `Arc<T>` is a type that lets us share ownership of data _across -->
336
+ <!-- threads_. -->
337
+ 要点は ` Arc<T> ` は _ スレッド間_ で所有権を共有可能にする方ということです。
338
+
301
339
``` ignore
302
340
use std::thread;
303
341
use std::sync::Arc;
@@ -317,9 +355,9 @@ fn main() {
317
355
}
318
356
```
319
357
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 . -->
321
359
<!-- This handle is then moved into the new thread. -->
322
- ここで ` Arc<T> ` について ` clone() ` を呼んで、内部のカウントを増やしています 。
360
+ 前回と同様に ` clone() ` を使って所有権を持った新たなハンドルを作っています 。
323
361
そして、このハンドルは新たなスレッドに移動されます。
324
362
325
363
<!-- And... still gives us an error. -->
@@ -332,20 +370,26 @@ fn main() {
332
370
^~~~
333
371
```
334
372
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スレッドしか内容の値を変更できないことを保障する型が必要そうです。
349
393
350
394
<!-- For that, we can use the `Mutex<T>` type! -->
351
395
そのためには、 ` Mutex<T> ` 型を使うことができます!
@@ -377,9 +421,24 @@ fn main() {
377
421
among the threads. -->
378
422
` i ` の値はクロージャへ束縛(コピー)されるだけで、スレッド間で共有されるわけではないことに注意してください。
379
423
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 -->
381
440
<!-- [`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 ) メソッドは次のシグネチャを持つことを気をつけて下さい 。
383
442
384
443
``` ignore
385
444
fn lock(&self) -> LockResult<MutexGuard<T>>
@@ -410,7 +469,7 @@ thread::spawn(move || {
410
469
```
411
470
412
471
<!-- 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()` -->
414
473
<!-- it to get a reference to the data. Real code would have more robust error handling -->
415
474
<!-- here. We're then free to mutate it, since we have the lock. -->
416
475
まず、 ` lock() ` を呼び、mutex のロックを獲得します。
@@ -451,6 +510,10 @@ use std::sync::mpsc;
451
510
fn main () {
452
511
let data = Arc :: new (Mutex :: new (0 ));
453
512
513
+ # // `tx` is the "transmitter" or "sender"
514
+ # // `rx` is the "receiver"
515
+ // `tx` は送信(transmitter)
516
+ // `rx` は受信(receiver)
454
517
let (tx , rx ) = mpsc :: channel ();
455
518
456
519
for _ in 0 .. 10 {
@@ -470,14 +533,14 @@ fn main() {
470
533
}
471
534
```
472
535
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` -->
474
537
<!-- a simple `()` down the channel, and then wait for ten of them to come back. -->
475
538
` mpsc::channel() ` メソッドを使って、新たなチャネルを生成しています。
476
- そして、ただの ` () ` をチャネルを通じて単に ` send ` し、それが10個戻ってくるのを待機します。
539
+ そして、ただの ` () ` をチャネルを通じて ` send ` し、それが10個戻ってくるのを待機します。
477
540
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 -->
479
542
<!-- is `Send` over the channel! -->
480
- このチャネルはただシグナルを送っているだけですが 、 ` Send ` であるデータならばなんでもこのチャネルを通じて送れます!
543
+ このチャネルはシグナルを送っているだけですが 、 ` Send ` であるデータならばなんでもこのチャネルを通じて送れます!
481
544
482
545
``` rust
483
546
use std :: thread;
0 commit comments