Skip to content

Commit 8ae67c6

Browse files
authored
Translate races.md (#50)
1 parent ac865a1 commit 8ae67c6

File tree

2 files changed

+65
-22
lines changed

2 files changed

+65
-22
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* [例外安全性](exception-safety.md)
3838
* [ポイゾニング](poisoning.md)
3939
* [並行性](concurrency.md)
40-
* [Races](races.md)
40+
* [競合](races.md)
4141
* [Send and Sync](send-and-sync.md)
4242
* [Atomics](atomics.md)
4343
* [Implementing Vec](vec.md)

src/races.md

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,103 @@
1+
<!--
12
# Data Races and Race Conditions
3+
-->
24

5+
# データ競合と競合状態
6+
7+
<!--
38
Safe Rust guarantees an absence of data races, which are defined as:
9+
-->
10+
11+
安全な Rust では、データ競合が存在しないことが保証されています。
12+
データ競合は、以下のように定義されています。
413

14+
<!--
515
* two or more threads concurrently accessing a location of memory
616
* one of them is a write
717
* one of them is unsynchronized
18+
-->
819

20+
* 2 つ以上のスレッドが並行にメモリ上の場所にアクセスしている
21+
* この内 1 つは書き込み
22+
* この内 1 つは非同期
23+
24+
<!--
925
A data race has Undefined Behavior, and is therefore impossible to perform
1026
in Safe Rust. Data races are *mostly* prevented through rust's ownership system:
1127
it's impossible to alias a mutable reference, so it's impossible to perform a
1228
data race. Interior mutability makes this more complicated, which is largely why
1329
we have the Send and Sync traits (see below).
30+
-->
31+
32+
データ競合は未定義動作を含み、そしてそれ故に安全な Rust で発生させることは不可能です。
33+
データ競合は Rust の所有権システムによって*ほとんど*防がれています。可変参照の
34+
エイリアスを生成することは不可能ですから、データ競合を起こすことは不可能です。
35+
内部可変性はこれをもっと複雑にします。これが、 Send トレイトと Sync トレイトが
36+
何故存在するかということの主な理由です (以下を見てください) 。
1437

38+
<!--
1539
**However Rust does not prevent general race conditions.**
40+
-->
1641

42+
**しかしながら Rust は、一般的な競合状態を防ぎません。**
43+
44+
<!--
1745
This is pretty fundamentally impossible, and probably honestly undesirable. Your
1846
hardware is racy, your OS is racy, the other programs on your computer are racy,
1947
and the world this all runs in is racy. Any system that could genuinely claim to
2048
prevent *all* race conditions would be pretty awful to use, if not just
2149
incorrect.
50+
-->
51+
52+
これは根本的に不可能で、そして多分本当に望まれていないものです。ハードウェアは
53+
競合状態を起こし、 OS も競合状態を起こし、コンピュータの他のプログラムも競合状態を起こし、
54+
そして世界中にある全てのプログラムも競合状態を起こします。どんなシステムでも、
55+
*全ての*競合状態を防げると喧伝しているようなものは、単に間違っているだけではなく、
56+
本当に使いづらいものとなるでしょう。
2257

58+
<!--
2359
So it's perfectly "fine" for a Safe Rust program to get deadlocked or do
2460
something nonsensical with incorrect synchronization. Obviously such a program
2561
isn't very good, but Rust can only hold your hand so far. Still, a race
2662
condition can't violate memory safety in a Rust program on its own. Only in
2763
conjunction with some other unsafe code can a race condition actually violate
2864
memory safety. For instance:
65+
-->
66+
67+
ですから、安全な Rust のプログラムがデッドロックに陥ったり、正しくない同期によって何か
68+
馬鹿げたことを行なっても、これは全く "問題ない" のです。明らかにそのようなプログラムは、
69+
本当に良くないです。ですが、 Rust は今までのところ、プログラマに我慢してもらうしか出来ないのです。
70+
それでも Rust のプログラムだけでは、競合状態において、メモリ安全性を侵害することは出来ません。
71+
何か他のアンセーフなコードと組み合わせることだけでしか、実際に競合状態において、
72+
メモリ安全性を侵害することが出来ないのです。例:
2973

3074
```rust,no_run
3175
use std::thread;
3276
use std::sync::atomic::{AtomicUsize, Ordering};
3377
use std::sync::Arc;
3478
3579
let data = vec![1, 2, 3, 4];
36-
// Arc so that the memory the AtomicUsize is stored in still exists for
37-
// the other thread to increment, even if we completely finish executing
38-
// before it. Rust won't compile the program without it, because of the
39-
// lifetime requirements of thread::spawn!
80+
// Arc にすることで、 他のスレッドより前に完全に実行が終了しても、 AtomicUsize
81+
// 保存されているメモリが、他のスレッドがインクリメントするために存在し続けます。
82+
// これ無しにはコンパイルできません。なぜなら、 thread::spawn が
83+
// ライフタイムを必要とするからです!
4084
let idx = Arc::new(AtomicUsize::new(0));
4185
let other_idx = idx.clone();
4286
43-
// `move` captures other_idx by-value, moving it into this thread
87+
// `move` によって other_idx が値でキャプチャされ、このスレッドにムーブされます
4488
thread::spawn(move || {
45-
// It's ok to mutate idx because this value
46-
// is an atomic, so it can't cause a Data Race.
89+
// idx を変更しても大丈夫です。この値はアトミックだからです。
90+
// ですからデータ競合は起こりません。
4791
other_idx.fetch_add(10, Ordering::SeqCst);
4892
});
4993
50-
// Index with the value loaded from the atomic. This is safe because we
51-
// read the atomic memory only once, and then pass a copy of that value
52-
// to the Vec's indexing implementation. This indexing will be correctly
53-
// bounds checked, and there's no chance of the value getting changed
54-
// in the middle. However our program may panic if the thread we spawned
55-
// managed to increment before this ran. A race condition because correct
56-
// program execution (panicking is rarely correct) depends on order of
57-
// thread execution.
94+
// アトミックなものからロードした値を使用してインデックス指定をします。これは安全です。
95+
// なぜなら、アトミックメモリから読み込み、その値のコピーを Vec のインデックス実装に
96+
// 渡すからです。このインデックス指定では、正しく境界チェックが行なわれ、そして途中で
97+
// 値が変わることはありません。しかし、もしスポーンされたスレッドが、なんとかして実行前に
98+
// インクリメントするならば、このプログラムはパニックするかもしれません。
99+
// 正しいプログラムの実行 (パニックすることはほとんど正しくありません) は、スレッドの
100+
// 実行順序に依存するため、競合状態となります。
58101
println!("{}", data[idx.load(Ordering::SeqCst)]);
59102
```
60103

@@ -68,18 +111,18 @@ let data = vec![1, 2, 3, 4];
68111
let idx = Arc::new(AtomicUsize::new(0));
69112
let other_idx = idx.clone();
70113
71-
// `move` captures other_idx by-value, moving it into this thread
114+
// `move` によって other_idx が値でキャプチャされ、このスレッドにムーブされます
72115
thread::spawn(move || {
73-
// It's ok to mutate idx because this value
74-
// is an atomic, so it can't cause a Data Race.
116+
// idx を変更しても大丈夫です。この値はアトミックだからです。
117+
// ですからデータ競合起こりません。
75118
other_idx.fetch_add(10, Ordering::SeqCst);
76119
});
77120
78121
if idx.load(Ordering::SeqCst) < data.len() {
79122
unsafe {
80-
// Incorrectly loading the idx after we did the bounds check.
81-
// It could have changed. This is a race condition, *and dangerous*
82-
// because we decided to do `get_unchecked`, which is `unsafe`.
123+
// 境界チェックを行なった後、間違えて idx をロードしてしまいます。
124+
// この値は変わってしまったかもしれません。これは競合状態で、*危険*です。
125+
// なぜなら `unsafe` である `get_unchecked` を行なったからです。
83126
println!("{}", data.get_unchecked(idx.load(Ordering::SeqCst)));
84127
}
85128
}

0 commit comments

Comments
 (0)