@@ -131,6 +131,59 @@ fn main() {
131
131
}
132
132
```
133
133
134
+ <!-- As closures can capture variables from their environment, we can also try to -->
135
+ <!-- bring some data into the other thread: -->
136
+ クロージャは環境から変数を捕捉出来るので、スレッドにデータを取り込もうとすることも出来ます。
137
+
138
+
139
+ ``` rust,ignore
140
+ use std::thread;
141
+
142
+ fn main() {
143
+ let x = 1;
144
+ thread::spawn(|| {
145
+ println!("x is {}", x);
146
+ });
147
+ }
148
+ ```
149
+
150
+ <!-- However, this gives us an error: -->
151
+ しかし、これはエラーです。
152
+
153
+ ``` text
154
+ 5:19: 7:6 error: closure may outlive the current function, but it
155
+ borrows `x`, which is owned by the current function
156
+ ...
157
+ 5:19: 7:6 help: to force the closure to take ownership of `x` (and any other referenced variables),
158
+ use the `move` keyword, as shown:
159
+ thread::spawn(move || {
160
+ println!("x is {}", x);
161
+ });
162
+ ```
163
+
164
+ <!-- This is because by default closures capture variables by reference, and thus the -->
165
+ <!-- closure only captures a _reference to `x`_. This is a problem, because the -->
166
+ <!-- thread may outlive the scope of `x`, leading to a dangling pointer. -->
167
+ これはクロージャはデフォルトで変数を参照で捕捉するためクロージャは _ ` x ` への参照_ のみを捕捉するからです。
168
+ これは問題です。なぜならスレッドは ` x ` のスコープよに長生きするかもしれないのでダングリングポインタを招きかねません。
169
+
170
+ <!-- To fix this, we use a `move` closure as mentioned in the error message. `move` -->
171
+ <!-- closures are explained in depth [here](closures.html#move-closures); basically -->
172
+ <!-- they move variables from their environment into themselves. -->
173
+ これを直すにはエラーメッセージにあるように ` move ` クロージャを使います。
174
+ ` move ` クロージャは [ こちら] ( closures.html#move-closures ) で詳細に説明されていますが、基本的には変数を環境からクロージャへムーブします。
175
+
176
+ ``` rust
177
+ use std :: thread;
178
+
179
+ fn main () {
180
+ let x = 1 ;
181
+ thread :: spawn (move || {
182
+ println! (" x is {}" , x );
183
+ });
184
+ }
185
+ ```
186
+
134
187
<!-- Many languages have the ability to execute threads, but it's wildly unsafe. -->
135
188
<!-- There are entire books about how to prevent errors that occur from shared -->
136
189
<!-- mutable state. Rust helps out with its type system here as well, by preventing -->
@@ -169,9 +222,9 @@ shared mutable state がとてもとても悪いものであるということ
169
222
ポインタの誤った使用の防止には [ 所有権のシステム] ( ownership.html ) が役立ちますが、このシステムはデータ競合を排除する際にも同様に一役買います。
170
223
データ競合は、並行性のバグの中で最悪なものの一つです。
171
224
172
- <!-- As an example, here is a Rust program that would have a data race in many -->
225
+ <!-- As an example, here is a Rust program that could have a data race in many -->
173
226
<!-- languages. It will not compile: -->
174
- 例として、多くの言語で起こるようなデータ競合を含んだRustプログラムをあげます 。
227
+ 例として、多くの言語で起こりうるようなデータ競合を含んだRustプログラムをあげます 。
175
228
これは、コンパイルが通りません。
176
229
177
230
``` ignore
@@ -201,33 +254,89 @@ fn main() {
201
254
```
202
255
203
256
<!-- Rust knows this wouldn't be safe! If we had a reference to `data` in each -->
204
- <!-- thread, and the thread takes ownership of the reference, we'd have three -->
205
- <!-- owners! -->
257
+ <!-- thread, and the thread takes ownership of the reference, we'd have three owners! -->
258
+ <!-- `data` gets moved out of `main` in the first call to `spawn()`, so subsequent -->
259
+ <!-- calls in the loop cannot use this variable. -->
206
260
Rustはこれが安全でないだろうと知っているのです!
207
261
もし、各スレッドに ` data ` への参照があり、スレッドごとにその参照の所有権があるとしたら、3人の所有者がいることになってしまうのです!
262
+ ` data ` は最初の ` spawn ` の呼び出しで ` main ` からムーブしてしまっているので、ループ内の続く呼び出しはこの変数を使えないのです。
263
+
264
+ <!-- Note that this specific example will not cause a data race since different array -->
265
+ <!-- indices are being accessed. But this can't be determined at compile time, and in -->
266
+ <!-- a similar situation where `i` is a constant or is random, you would have a data -->
267
+ <!-- race. -->
268
+ この例では配列の異ったインデックスにアクセスしているのでデータ競合は起きません。
269
+ しかしこの分離性はコンパイル時に決定出来ませんし ` i ` が定数や乱数だった時にデータ競合が起きます。
270
+
271
+ <!-- So, we need some type that lets us have more than one owning reference to a -->
272
+ <!-- value. Usually, we'd use `Rc<T>` for this, which is a reference counted type -->
273
+ <!-- that provides shared ownership. It has some runtime bookkeeping that keeps track -->
274
+ <!-- of the number of references to it, hence the "reference count" part of its name. -->
275
+ そのため、1つの値に対して2つ以上の所有権を持った参照を持てるような型が必要です。
276
+ 通常、この用途には ` Rc<T> ` を使います。これは所有権の共有を提供する参照カウントの型です。
277
+ 実行時にある程度の管理コストを払って、値への参照の数をカウントします。
278
+ なので名前に参照カウント(reference count) が付いているのです。
279
+
280
+ <!-- Calling `clone()` on an `Rc<T>` will return a new owned reference and bump the -->
281
+ <!-- internal reference count. We create one of these for each thread: -->
282
+ ` Rc<T> ` に対して ` clone() ` を呼ぶと新たな所有権を持った参照を返し、内部の参照カウント数を増やします。
283
+ スレッドそれぞれで ` clone() ` を取ります:
284
+
285
+ ``` ignore
286
+ use std::thread;
287
+ use std::time::Duration;
288
+ use std::rc::Rc;
289
+
290
+ fn main() {
291
+ let mut data = Rc::new(vec![1, 2, 3]);
292
+
293
+ for i in 0..3 {
294
+ # // create a new owned reference
295
+ // 所有権を持った参照を新たに作る
296
+ let data_ref = data.clone();
297
+
298
+ # // use it in a thread
299
+ // スレッド内でそれを使う
300
+ thread::spawn(move || {
301
+ data_ref[i] += 1;
302
+ });
303
+ }
208
304
209
- <!-- So, we need some type that lets us have more than one reference to a value and -->
210
- <!-- that we can share between threads, that is it must implement `Sync`. -->
211
- そのため、1つの値に対して2つ以上の参照を持てるようにして、スレッド間で共有できるような型が必要です。
212
- そして、その型は ` Sync ` を実装していなければなりません。
305
+ thread::sleep(Duration::from_millis(50));
306
+ }
307
+ ```
213
308
214
- <!-- We'll use `Arc<T>`, Rust's standard atomic reference count type, which -->
215
- <!-- wraps a value up with some extra runtime bookkeeping which allows us to -->
216
- <!-- share the ownership of the value between multiple references at the same time. -->
217
- Rustの標準アトミック参照カウント型である ` Arc<T> ` を使いましょう。
218
- これは複数の参照間で値の所有権を同時に共有できるように、値を特別な実行時の管理用データでくるむものです。
309
+ <!-- This won't work, however, and will give us the error: -->
310
+ これは動作せず、以下のようなエラーを出します:
219
311
220
- <!-- The bookkeeping consists of a count of how many of these references exist to -->
221
- <!-- the value, hence the reference count part of the name. -->
222
- その管理用データには、値への参照がいくつ存在しているかというカウントが記録されています。
223
- すなわち名前の「参照カウント」の部分にあたります。
312
+ ``` text
313
+ 13:9: 13:22 error: the trait bound `alloc::rc::Rc<collections::vec::Vec<i32>> : core::marker::Send`
314
+ is not satisfied
315
+ ...
316
+ 13:9: 13:22 note: `alloc::rc::Rc<collections::vec::Vec<i32>>`
317
+ cannot be sent between threads safely
318
+ ```
319
+
320
+ <!-- As the error message mentions, `Rc` cannot be sent between threads safely. This -->
321
+ <!-- is because the internal reference count is not maintained in a thread safe -->
322
+ <!-- matter and can have a data race. -->
323
+ エラーメッセージで言及があるように、 ` Rc ` は安全に別のスレッドに送ることが出来ません。
324
+ これは内部の参照カウントがスレッドセーフに管理されていないのでデータ競合を起こし得るからです。
325
+
326
+ <!-- To solve this, we'll use `Arc<T>`, Rust's standard atomic reference count type. -->
327
+ この問題を解決するために、 ` Arc<T> ` を使います。Rustの標準のアトミックな参照カウント型です。
224
328
225
329
<!-- The Atomic part means `Arc<T>` can safely be accessed from multiple threads. -->
226
330
<!-- To do this the compiler guarantees that mutations of the internal count use -->
227
331
<!-- indivisible operations which can't have data races. -->
228
332
「アトミック」という部分は ` Arc<T> ` が複数スレッドから安全にアクセスできることを意味しています。
229
333
このためにコンパイラは、内部のカウントの更新には、データ競合が起こりえない分割不能な操作が用いられることを保証します。
230
334
335
+
336
+ <!-- In essence, `Arc<T>` is a type that lets us share ownership of data _across -->
337
+ <!-- threads_. -->
338
+ 要点は ` Arc<T> ` は _ スレッド間_ で所有権を共有可能にする型ということです。
339
+
231
340
``` ignore
232
341
use std::thread;
233
342
use std::sync::Arc;
@@ -247,9 +356,9 @@ fn main() {
247
356
}
248
357
```
249
358
250
- <!-- We now call `clone()` on our `Arc<T>`, which increases the internal count . -->
359
+ <!-- Similarly to last time, we use `clone()` to create a new owned handle . -->
251
360
<!-- This handle is then moved into the new thread. -->
252
- ここで ` Arc<T> ` について ` clone() ` を呼んで、内部のカウントを増やしています 。
361
+ 前回と同様に ` clone() ` を使って所有権を持った新たなハンドルを作っています 。
253
362
そして、このハンドルは新たなスレッドに移動されます。
254
363
255
364
<!-- And... still gives us an error. -->
@@ -262,20 +371,26 @@ fn main() {
262
371
^~~~
263
372
```
264
373
265
- <!-- `Arc<T>` assumes one more property about its contents to ensure that it is safe -->
266
- <!-- to share across threads: it assumes its contents are `Sync`. This is true for -->
267
- <!-- our value if it's immutable, but we want to be able to mutate it, so we need -->
268
- <!-- something else to persuade the borrow checker we know what we're doing. -->
269
- ` Arc<T> ` はスレッドをまたいだ共有を安全にするために、その中身に対してもう一つの仮定をおいています。
270
- それは、中身が ` Sync ` であるという仮定です。
271
- この仮定は値がイミュータブルであるときは真になりますが、今回は値を変化できるようにしたいです。
272
- そのため、借用チェッカに対し、我々は自分たちが何をやっているかを知っています、と説得するための何かが必要になります。
273
-
274
- <!-- It looks like we need some type that allows us to safely mutate a shared value, -->
275
- <!-- for example a type that can ensure only one thread at a time is able to -->
276
- <!-- mutate the value inside it at any one time. -->
277
- 共有された値を安全に変更できるようにするための型が必要そうです。
278
- 例えば、どの時点においても、同時に一つのスレッドのなかでしか値は変更できないということを保証できる型です。
374
+ <!-- `Arc<T>` by default has immutable contents. It allows the _sharing_ of data -->
375
+ <!-- between threads, but shared mutable data is unsafe and when threads are -->
376
+ <!-- involved can cause data races! -->
377
+ ` Arc<T> ` が保持する値はデフォルトでイミュータブルです。
378
+ スレッド間での _ 共有_ はしてくれますがスレッドが絡んだ時の共有されたミュータブルなデータはデータ競合を引き起こし得ます。
379
+
380
+ <!-- Usually when we wish to make something in an immutable position mutable, we use -->
381
+ <!-- `Cell<T>` or `RefCell<T>` which allow safe mutation via runtime checks or -->
382
+ <!-- otherwise (see also: [Choosing Your Guarantees](choosing-your-guarantees.html)). -->
383
+ <!-- However, similar to `Rc`, these are not thread safe. If we try using these, we -->
384
+ <!-- will get an error about these types not being `Sync`, and the code will fail to -->
385
+ <!-- compile. -->
386
+ 通常イミュータブルな位置のものをミュータブルにしたい時は ` Cell<T> ` 又は ` RefCell<T> ` が実行時のチェックあるいは他の方法で安全に変更する手段を提供してくれる(参考: [ 保障を選ぶ] ( choosing-your-guarantees.html ) )のでそれを使います。
387
+ しかしながら ` Rc ` と同じくこれらはスレッドセーフではありません。
388
+ これらを使おうとすると ` Sync ` でない旨のエラーが出てコンパイルに失敗します。
389
+
390
+ <!-- It looks like we need some type that allows us to safely mutate a shared value -->
391
+ <!-- across threads, for example a type that can ensure only one thread at a time is -->
392
+ <!-- able to mutate the value inside it at any one time. -->
393
+ スレッド間で共有された値を安全に変更出来る型、例えばどの瞬間でも同時に1スレッドしか内容の値を変更できないことを保障する型が必要そうです。
279
394
280
395
<!-- For that, we can use the `Mutex<T>` type! -->
281
396
そのためには、 ` Mutex<T> ` 型を使うことができます!
@@ -307,9 +422,24 @@ fn main() {
307
422
among the threads. -->
308
423
` i ` の値はクロージャへ束縛(コピー)されるだけで、スレッド間で共有されるわけではないことに注意してください。
309
424
310
- <!-- Also note that [`lock`](../std/sync/struct.Mutex.html#method.lock) method of -->
425
+ <!-- We're "locking" the mutex here. A mutex (short for "mutual exclusion"), as -->
426
+ <!-- mentioned, only allows one thread at a time to access a value. When we wish to -->
427
+ <!-- access the value, we use `lock()` on it. This will "lock" the mutex, and no -->
428
+ <!-- other thread will be able to lock it (and hence, do anything with the value) -->
429
+ <!-- until we're done with it. If a thread attempts to lock a mutex which is already -->
430
+ <!-- locked, it will wait until the other thread releases the lock. -->
431
+ ここではmutexを「ロック」しているのです。
432
+ mutex(「mutual exclusion(訳注: 相互排他)」の略)は前述の通り同時に1つのスレッドからのアクセスしか許しません。
433
+ 値にアクセスしようと思ったら、 ` lock() ` を使います。これは値を使い終わるまでmutexを「ロック」して他のどのスレッドもロック出来ない(そして値に対して何も出来ない)ようにします。
434
+ もし既にロックされているmutexをロックしようとすると別のスレッドがロックを解放するまで待ちます。
435
+
436
+ <!-- The lock "release" here is implicit; when the result of the lock (in this case, -->
437
+ <!-- `data`) goes out of scope, the lock is automatically released. -->
438
+ ここでの「解放」は暗黙的です。ロックの結果(この場合は ` data ` )がスコープを出ると、ロックは自動で解放されます
439
+
440
+ <!-- Note that [`lock`](../std/sync/struct.Mutex.html#method.lock) method of -->
311
441
<!-- [`Mutex`](../std/sync/struct.Mutex.html) has this signature: -->
312
- また、 [ ` Mutex ` ] ( ../std/sync/struct.Mutex.html ) の [ ` lock ` ] ( ../std/sync/struct.Mutex.html#method.lock ) メソッドは以下のシグネチャを持つことにも注意してください 。
442
+ [ ` Mutex ` ] ( ../std/sync/struct.Mutex.html ) の [ ` lock ` ] ( ../std/sync/struct.Mutex.html#method.lock ) メソッドは次のシグネチャを持つことを気をつけて下さい 。
313
443
314
444
``` ignore
315
445
fn lock(&self) -> LockResult<MutexGuard<T>>
@@ -340,7 +470,7 @@ thread::spawn(move || {
340
470
```
341
471
342
472
<!-- First, we call `lock()`, which acquires the mutex's lock. Because this may fail, -->
343
- <!-- it returns an `Result<T, E>`, and because this is just an example, we `unwrap()` -->
473
+ <!-- it returns a `Result<T, E>`, and because this is just an example, we `unwrap()` -->
344
474
<!-- it to get a reference to the data. Real code would have more robust error handling -->
345
475
<!-- here. We're then free to mutate it, since we have the lock. -->
346
476
まず、 ` lock() ` を呼び、mutex のロックを獲得します。
@@ -381,6 +511,10 @@ use std::sync::mpsc;
381
511
fn main () {
382
512
let data = Arc :: new (Mutex :: new (0 ));
383
513
514
+ # // `tx` is the "transmitter" or "sender"
515
+ # // `rx` is the "receiver"
516
+ // `tx` は送信(transmitter)
517
+ // `rx` は受信(receiver)
384
518
let (tx , rx ) = mpsc :: channel ();
385
519
386
520
for _ in 0 .. 10 {
@@ -400,14 +534,14 @@ fn main() {
400
534
}
401
535
```
402
536
403
- <!-- We use the `mpsc::channel()` method to construct a new channel. We just `send` -->
537
+ <!-- We use the `mpsc::channel()` method to construct a new channel. We `send` -->
404
538
<!-- a simple `()` down the channel, and then wait for ten of them to come back. -->
405
539
` mpsc::channel() ` メソッドを使って、新たなチャネルを生成しています。
406
- そして、ただの ` () ` をチャネルを通じて単に ` send ` し、それが10個戻ってくるのを待機します。
540
+ そして、ただの ` () ` をチャネルを通じて ` send ` し、それが10個戻ってくるのを待機します。
407
541
408
- <!-- While this channel is just sending a generic signal, we can send any data that -->
542
+ <!-- While this channel is sending a generic signal, we can send any data that -->
409
543
<!-- is `Send` over the channel! -->
410
- このチャネルはただシグナルを送っているだけですが 、 ` Send ` であるデータならばなんでもこのチャネルを通じて送れます!
544
+ このチャネルはシグナルを送っているだけですが 、 ` Send ` であるデータならばなんでもこのチャネルを通じて送れます!
411
545
412
546
``` rust
413
547
use std :: thread;
0 commit comments