|
1 | 1 | # 识别并行编程的问题 |
2 | 2 |
|
3 | | -当在并行魔鬼居住的大地上战斗之时,勇敢的键盘战士将会遇到一些经典的问题。当没有经验的程序员使用workers和共享状态相结合时,这些问题时有发生。这些问题将会在下面的小节中进行描述。 |
| 3 | +勇敢的键盘战士在并行编程幽灵居住的土地上作战时可能会遇到一些经典问题。 当没有经验的程序员使用结合了共享状态的 worker 时,许多这些问题会更频繁地发生。 其中一些问题将在以下各节中进行描述。 |
4 | 4 |
|
5 | 5 | ## 死锁 |
6 | 6 |
|
7 | | -死锁是这么一种情形,有两个或两个以上的workers继续为了资源的释放而无限期的等待,而资源由于某些原因被这一组的一个worker所占用。为了更好的理解,我们将使用另一个真实的案例。想象银行的入口有一个旋转门。顾客A走向了允许他进入银行的一侧,而顾客B试图从旋转门入口的一侧离开银行,这样的话门将被卡在那里,两个顾客哪里都去不了。这种情形在现实中会很搞笑,但是在编程中将会是一个悲剧。 |
| 7 | +**死锁**(Deadlock)是指两个或多个 worker 无限期地等待资源释放的情况,由于某种原因,该资源被同一组的 worker 阻塞。 为了更好地理解,我们将使用另一个真实案例。 想象一下入口处有一扇旋转门的银行。 客户 A 转向一侧,这将允许他进入银行,而客户 B 试图通过这个旋转门的入口侧离开银行,这样两个客户都会被困在推门处,但无处可去。 这种情况在现实生活中会很滑稽,但在编程中会很悲惨。 |
8 | 8 |
|
9 | | -> 死锁是这么一个现象,进程都在等待一个释放它们任务出现的情况,而这个情况永远不会出现。 |
| 9 | +!!! info "" |
| 10 | + |
| 11 | +**死锁**(Deadlock)是一种现象,其中进程等待释放任务条件的发生,但这种情况永远不会发生 |
10 | 12 |
|
11 | 13 | ## 饥饿 |
12 | 14 |
|
13 | 15 | 这个问题是由于一个或者多个进程不公平的竞争所引起的副作用,这会花费更多的时间来执行任务。想象有一组进程,A进程正在执行繁重的任务,而且这个任务还有数据处理优先级。现在,想象一下,高优先级的进程A持续不断的占用CPU,而低优先级的进程B将永远没有机会。因此可以说进程B在CPU周期中是饥饿的。 |
14 | 16 |
|
15 | | -> 饥饿是由于进程排名中差劲的调整策略引起的。 |
| 17 | +> **饥饿**(Starvation)是由于进程排名策略调整不当造成的。 |
16 | 18 |
|
17 | 19 | ## 竞态条件 |
18 | 20 |
|
19 | | -当一个进程的结果取决于执行结果的顺序,而这个顺序由于缺乏同步机制而被破坏,这个时候我们将面临竞态条件。在大的系统中,它们造成的问题将会难以过滤。举个栗子,有一对夫妇有一个联名的账户,在他们操作之前初始的余额是$100.下表显示了常规的有保护机制、预期的事实顺序以及结果情况: |
| 21 | +当一个进程的结果取决于执行结果的顺序,而这个顺序由于缺乏同步机制而被打破时,我们就会面临竞态条件。 它们是由在大型系统中极难过滤的问题引起的。 例如,一对夫妇有一个联名账户; 操作前的初始余额为 100 美元。 下表显示了常规情况,其中有保护机制和预期事实的顺序,以及结果: |
| 22 | + |
| 23 | +!!! info "常规操作而不会出现静态条件" |
20 | 24 |
|
21 | | - |
| 25 | +| 丈夫 | 妻子 | 账户余额(美元) | |
| 26 | +| -------- | -------- | ---------------- | |
| 27 | +| | | 100 | |
| 28 | +| 读取余额 | | 100 | |
| 29 | +| 存款20 | | 100 | |
| 30 | +| 结束操作 | | 120 | |
| 31 | +| | 读取余额 | 120 | |
| 32 | +| | 取款10 | 120 | |
| 33 | +| | 结束操作 | 110 | |
22 | 34 |
|
23 | 35 | 在下表中,有问题的场景出现了。假设账户没有同步机制,并且操作的顺序也和预期不一样。 |
24 | 36 |
|
25 | | - |
| 37 | +!!! info "类比在联合账户和竞争条件下平衡问题" |
| 38 | + |
| 39 | +| 丈夫 | 妻子 | 账户余额(美元) | |
| 40 | +| --------------------- | --------------------- | ---------------- | |
| 41 | +| | | 100 | |
| 42 | +| 读取余额 | | 100 | |
| 43 | +| 取款100 | | 100 | |
| 44 | +| | 读取余额 | 100 | |
| 45 | +| | 取款10 | 100 | |
| 46 | +| 结束操作<br/>更新余额 | | 0 | |
| 47 | +| | 结束操作<br/>更新余额 | 90 | |
| 48 | + |
| 49 | +由于在操作的顺序中意外的缺乏同步,最终结果存在明显的不一致。并行编程的特征之一是不确定性。无法预见两个 worker 将在什么时候运行,甚至谁先运行。 因此,同步机制必不可少。 |
26 | 50 |
|
27 | | -由于在操作的顺序中意外的没有同步,最终的结果将会明显不一致。并行编程的一个特点就是不确定性。当两个workers都正在运行或者它们中的一个第一个运行的时候,结果将会是不可预见的。因此同步机制是必不可少的。 |
| 51 | +!!! info "" |
28 | 52 |
|
29 | | -> 不确定性,如果缺乏同步机制,将会导致竞态条件的问题。 |
| 53 | +**不确定性**(Non-determinism),如果与缺乏同步机制相结合,可能会导致竞争条件问题 |
0 commit comments