Skip to content

Commit 6770078

Browse files
author
wangchao
committed
更新
1 parent b5f5ed8 commit 6770078

File tree

92 files changed

+1060
-620
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+1060
-620
lines changed

docs/第一章/在并行编程通信.md renamed to docs/chapter1/communicating_in_parallel_programming.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
##在并行编程通信
1+
# 在并行编程通信
22

33
在并行编程中,workers被送来执行任务,而执行任务常常需要建立通信,以便可以合作解决一个问题。
44
在大多数情况下,通信以一种可以在workers之间进行数据交换的方式被建立。当说到并行编程,有两种通信方式广为人知:共享状态和消息传递。在下面的章节中,将对这两种方式进行简要描述。
55

6-
###理解共享状态
6+
## 理解共享状态
77

88
在workers中最有名的一种通信方式就是共享状态。分享状态似乎是一个简单的使用,但是这会有许多的陷阱,因为若其中某个进程对共享的资源执行了一项无效的操作会影响到所有其它的进程,从而导致一个不好的结果。这也是使在多台计算机之间进行分布式的程序成为不可能的显而易见的原因。
99

@@ -13,7 +13,7 @@ Mutex可以理解为一种特殊的过程变量,表示了访问数据的可靠
1313

1414
> 在某些情况下,当程序正在运行时,在一个变量中数据会有一个常数值,数据仅仅以只读的目的被分享。所以访问控制不是必须的,因为永远不会出现完整性问题。
1515
16-
###理解信息传递
16+
## 理解信息传递
1717

1818
运用消息传递是为了避免来自共享状态带来的数据访问控制以及同步的问题。消息传递包含一种在运行的进程中进行消息交换的机制。每当我们用分布式架构开发程序的时候,就能见到消息传递的使用,在网络中,消息交换被放在一个重要的位置。Erlang等语言,在它的并行体系结构中,就是使用这个模型来实现通信。由于每次数据交换都复制一份数据的拷贝,因此不会出现并发访问的问题。尽管内存使用看起来比共享内存状态要高,但是这个模型还是有一些优势的。优势如下:
1919

Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
##发现Python并行编程的工具
1+
# 发现Python并行编程的工具
22

33
由Guido Van Rossum创造的语言,是一种多泛型的,多用途的语言。由于它非常简单且易于维护,被世界各处广泛接受。它也被称为含有电池的语言。它有广泛的模块使其用起来更流畅。在并行编程中,Python有简化实现的内置和外部模块。本书基于Python3.X的。
44

5-
###Python的threading模块
5+
## Python的threading模块
66

7-
Python的threading模块提供了一个抽象层次的模块_thread,这是一个低层次的模块。当开发一个基于线程的并行系统的艰巨任务时,它为程序员提供了一些函数来帮助程序员的开发。线程模块的官方文档可以在<http://docs.python.org/3/library/
7+
Python的threading模块提供了一个抽象层次的模块_thread,这是一个低层次的模块。当开发一个基于线程的并行系统的艰巨任务时,它为程序员提供了一些函数来帮助程序员的开发。线程模块的官方文档可以在<<http://docs.python.org/3/library/>
88
threading.html?highlight=threading#module-threadin>找到。
99

10-
###Python的mutliprocess模块
10+
## Python的mutliprocess模块
1111

12-
multiprocessing模块旨在为基于进程的并行的使用提供一个简单的API。这个模块与线程模块类似,它简化了基于进程的并行系统的开发,这一点与线程模块没有什么不同。在Python社区中,基于进程的方法很流行,因为它是在解决出现在Python中CPU-Bound threads和GIL的使用的问题时的一个解决方案。多进程模块的官方文档可以在<http://docs.python.org/3/library/multiprocessing.html?highlight=multi
12+
multiprocessing模块旨在为基于进程的并行的使用提供一个简单的API。这个模块与线程模块类似,它简化了基于进程的并行系统的开发,这一点与线程模块没有什么不同。在Python社区中,基于进程的方法很流行,因为它是在解决出现在Python中CPU-Bound threads和GIL的使用的问题时的一个解决方案。多进程模块的官方文档可以在<<http://docs.python.org/3/library/multiprocessing.html?highlight=multi>
1313
processing#multiprocessing>找到。
1414

15-
###Python的parallel模块
15+
## Python的parallel模块
1616

1717
Python的parallel模块是外部模块,它提供了丰富的API,这些API利用进程的方法创建并行和分布式系统。这个模块是轻量级并且易安装的,它与其他的Python程序一起集成的。parallel模块可以在<http://parallelpython.com>找到。在那么多特性中,我们着重强调以下几点:
1818

@@ -22,10 +22,8 @@ Python的parallel模块是外部模块,它提供了丰富的API,这些API利
2222
* 容错性
2323
* 自发现计算资源
2424

25-
###Celery-分布式任务队列
25+
## Celery-分布式任务队列
2626

2727
Celery是一个用于创建分布式系统的极其优秀的模块,并且拥有很好的文档。它在并发形式上使用了至少三种不同类型的方法来执行任务:multiprocessing, Eventlet,和 Gevent。这项工作将会集中精力在多进程的方法的使用上。而且,只需要通过配置就能实现进程间的互联,这被留下来作为一个研究,以便读者能够建立一个与他/她的实验的一个比较。
2828

2929
Celery模块可以在官方的项目页面<http://celeryproject.org>得到。
30-
31-

docs/第一章/探索并行化的几种模式.md renamed to docs/chapter1/exploring_common_forms_of_parallelization.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
##探索并行化的几种模式
1+
# 探索并行化的几种模式
22

33
当我们试图定义并行系统的主要模式时,有困惑很正常。常常会有人提到并发系统和并行系统,这两个术语看起来像是讲的同一件事。然而实际上有着轻微的差异。
44

@@ -8,15 +8,15 @@
88
99
下图显示了一个并发程序方案:
1010

11-
![](https://github.com/Voidly/Img/blob/master/Parallel%20Programming%20with%20Python/Chapter%201/Concurrent%20programming%20scheme.png?raw=true)
11+
![1](https://github.com/Voidly/Img/blob/master/Parallel%20Programming%20with%20Python/Chapter%201/Concurrent%20programming%20scheme.png?raw=true)
1212

1313
并行编程可以被定义为一种方法,在那个方法中,程序数据创造workers在多核环境中同时执行指定的任务,在这些任务中它们不需要并发的接触CPU。
1414

1515
> 并行系统同时的运行任务。
1616
1717
下面的图显示了并行系统的概念:
1818

19-
![](https://github.com/Voidly/Img/blob/master/Parallel%20Programming%20with%20Python/Chapter%201/Parallel%20programming%20scheme.png?raw=true)
19+
![2](https://github.com/Voidly/Img/blob/master/Parallel%20Programming%20with%20Python/Chapter%201/Parallel%20programming%20scheme.png?raw=true)
2020

2121
分布式编程旨在在物理分离的计算机器(节点)之间通过消息交换数据来分享进程
2222

@@ -30,4 +30,4 @@
3030
3131
下图显示了一个分布式系统的方案:
3232

33-
![](https://github.com/Voidly/Img/blob/master/Parallel%20Programming%20with%20Python/Chapter%201/Distributed%20programming%20scheme.png?raw=true)
33+
![3](https://github.com/Voidly/Img/blob/master/Parallel%20Programming%20with%20Python/Chapter%201/Distributed%20programming%20scheme.png?raw=true)
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,29 @@
1-
##识别并行编程的问题
1+
# 识别并行编程的问题
22

33
当在并行魔鬼居住的大地上战斗之时,勇敢的键盘战士将会遇到一些经典的问题。当没有经验的程序员使用workers和共享状态相结合时,这些问题时有发生。这些问题将会在下面的小节中进行描述。
44

5-
###死锁
5+
## 死锁
66

77
死锁是这么一种情形,有两个或两个以上的workers继续为了资源的释放而无限期的等待,而资源由于某些原因被这一组的一个worker所占用。为了更好的理解,我们将使用另一个真实的案例。想象银行的入口有一个旋转门。顾客A走向了允许他进入银行的一侧,而顾客B试图从旋转门入口的一侧离开银行,这样的话门将被卡在那里,两个顾客哪里都去不了。这种情形在现实中会很搞笑,但是在编程中将会是一个悲剧。
88

99
> 死锁是这么一个现象,进程都在等待一个释放它们任务出现的情况,而这个情况永远不会出现。
1010
11-
###饥饿
11+
## 饥饿
1212

1313
这个问题是由于一个或者多个进程不公平的竞争所引起的副作用,这会花费更多的时间来执行任务。想象有一组进程,A进程正在执行繁重的任务,而且这个任务还有数据处理优先级。现在,想象一下,高优先级的进程A持续不断的占用CPU,而低优先级的进程B将永远没有机会。因此可以说进程B在CPU周期中是饥饿的。
1414

1515
> 饥饿是由于进程排名中差劲的调整策略引起的。
1616
17-
###竞态条件
17+
## 竞态条件
1818

1919
当一个进程的结果取决于执行结果的顺序,而这个顺序由于缺乏同步机制而被破坏,这个时候我们将面临竞态条件。在大的系统中,它们造成的问题将会难以过滤。举个栗子,有一对夫妇有一个联名的账户,在他们操作之前初始的余额是$100.下表显示了常规的有保护机制、预期的事实顺序以及结果情况:
2020

21-
![](https://github.com/Voidly/Img/blob/master/Parallel%20Programming%20with%20Python/Chapter%201/Presents%20baking%20operations%20without%20the%20chance%20of%20race%20conditions%20occurrence.png?raw=true)
21+
![1](https://github.com/Voidly/Img/blob/master/Parallel%20Programming%20with%20Python/Chapter%201/Presents%20baking%20operations%20without%20the%20chance%20of%20race%20conditions%20occurrence.png?raw=true)
2222

2323
在下表中,有问题的场景出现了。假设账户没有同步机制,并且操作的顺序也和预期不一样。
2424

25-
![](https://github.com/Voidly/Img/blob/master/Parallel%20Programming%20with%20Python/Chapter%201/Analogy%20to%20balance%20the%20problem%20in%20a%20joint%20account%20and%20race%20conditions.png?raw=true)
25+
![1](https://github.com/Voidly/Img/blob/master/Parallel%20Programming%20with%20Python/Chapter%201/Analogy%20to%20balance%20the%20problem%20in%20a%20joint%20account%20and%20race%20conditions.png?raw=true)
2626

2727
由于在操作的顺序中意外的没有同步,最终的结果将会明显不一致。并行编程的一个特点就是不确定性。当两个workers都正在运行或者它们中的一个第一个运行的时候,结果将会是不可预见的。因此同步机制是必不可少的。
2828

2929
> 不确定性,如果缺乏同步机制,将会导致竞态条件的问题。
30-
31-
32-
33-
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
##并行、并发以及分布式编程的对比分析
1+
# 并行、并发以及分布式编程的对比分析
22

33
并行编程可以被定义为一种模型,这个模型旨在创造一种能与被准备用于同时执行代码指令的环境相兼容的程序。并行技术被用于开发软件还不是很长。几年前,处理器在其它组件中只有一个在一段时间空间中一次只能执行一条指令的算术逻辑单元(ALU)。多年来,只有一个以Hz为衡量单位的时钟,被用来决定在给定的时间间隔里一个处理器能执行的指令数量。时钟的数量越多,那么执行的更多指令数量的潜力更大,比如说KHz(每秒数以千计的操作)、MHz(每秒数以百万计的操作)、以及现在的GHz(每秒数以千万计的操作)。
44

55
总结,每个周期处理器执行的指令越多,那么它执行的越快。在80年代,一个革命性的处理器步入人们的生活,Intel 80386,允许任务以预先执行的方式来执行,也就是说,它会阶段性的中断当前的程序来为另一个程序提供处理器时间;这意味着一种基于时间分片的伪并行处理的诞生。
66

77
在80年代末期,出现了Intel80486,它实现了一种管道系统,在实践中,这个系统将执行阶段划分为不同的子阶段。实际上,在一个处理器周期中,我们可能有不同的指令在一个子阶段同时被执行。
88

9-
所有的在前一节所提到的进步带来一些性能上的提升,但是这些仍然不够,我们所面对的微妙的问题,而这,被称为摩尔定律(<http://www.mooreslaw.org/>)。
9+
所有的在前一节所提到的进步带来一些性能上的提升,但是这些仍然不够,我们所面对的微妙的问题,而这,被称为摩尔定律(<http://www.mooreslaw.org/>{target="_blank"})。
1010

1111
探寻满足时钟高能耗的过程最终会被物理规则的限制所阻;处理器将消耗更高的能量,从而产生更多的热。此外,还有一个重大的问题,便携式电脑的市场在90年代正在加速扩张。所以,有一种能够使这些设备的电源能够持续长时间的远离插座的处理器是极其重要的。几个来自不同的制造商的技术和家庭的处理器诞生了。在服务器和大型主机领域,值得一提的是英特尔的Core(R)系列产品,该系列产品允许即使只有一个物理芯片,也能让操作系统模拟出存在不止一个的处理器。
1212

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
##总结
1+
# 总结
22

33
在这一章节,我们学了一些并行编程的概念,并学习了一些模型的优点以及缺点。在谈到并行性的时候对于一些问题或者潜在问题进行了一些简短的解释。我们也对Python的一些内置和外部的模块进行了简短的介绍,这让开发人员在建立并行系统时会更加轻松。
44

5-
在下一章节,我们会学习一些设计并行算法的技术。
5+
在下一章节,我们会学习一些设计并行算法的技术。
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
##小心Python GIL
1+
# 小心Python GIL
22

33
GIL是一种用于实现标准Python(也被称为CPython)的一种机制,是为了避免不同的线程同时执行字节码。在这门语言的使用者中,GIL存在的原因被激烈的讨论着。GIL被用于保护被CPython解释器使用的内存储器,因为CPython解析器并未实现为线程的并发访问的同步机制。在任何情况下,当我们决定使用线程时,GIL将会导致一个问题,这些往往是CPU受限。比如说,I/O Threads超出了GIL的范围。也许GIL机在Python的演变过程中带来的好处要多于坏处。显然,我们不能仅仅将效率作为评判一个事情是好是坏的唯一的标准。
44

55
很多情况下,使用多进程配合消息传递能更好的平衡可维护性、可扩展性以及性能之间的关系。然而,在某些情况下即使由于GIL的存在会降低效率也还是会需要线程。这时,所能做的就是写一些代码片段作为C语言的扩展,并且把它们嵌入到Python程序中。因此也是有替代品的,这应由开发人员分析真正的需求。那么问题来了,GIL一般来说是一个恶棍吗?重要的是要记住,PyPy团队正致力于将GIL从Python中移除的STM的实现。想了解有关此项目的更多细节,请访问<http://pypy.org/tmdonate.html>.
6-

docs/第一章/为什么使用并行编程.md renamed to docs/chapter1/why_use_parallel_programming.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
##为什么使用并行编程
1+
# 为什么使用并行编程
22

33
自从计算系统进化以来,它们已经开始提供一个能使我们以并行的方式运行指定软件的独立的某部分的机制,从而提升响应速度以及一般的性能。此外,我们可以很容易的验证配备有多个处理器以及多核的机器。那么,为什么不利用这个架构呢?
44

File renamed without changes.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
##设计并行算法
1+
# 设计并行算法
22

33
在开发并行系统时,在你编码之前,有几个方面你必须要留意。为了在任务中获得成功,从一开始将并行的问题列出来是至关重要的。在这一章节,我们将接触一些技术方面的解决方案。
44

@@ -7,4 +7,4 @@
77
- 分治技术
88
- 数据分解
99
- 用管道分解任务
10-
- 处理和映射
10+
- 处理和映射

0 commit comments

Comments
 (0)