python 并行编程概述
程序并行化的形式
程序并行化有以下三种形式,分别是:并发编程(Concurrent Programming)、并行编程(Parallel Programming )、分布式编程 (Distributed Programming)
并发编程(Concurrent Programming)
并发编程(Concurrent Programming)的模型图如下所示:
从图中可知,并发编程类似操作系统中的伪并行,任一时刻只有一个进程占用 CPU,通过调度控制不同的进程在不同时刻访问 CPU。
并行编程(Parallel Programming )
并行编程的模型图如下所示:
并行编程指在多核环境中,同一时间每个核都可以允许一个进程运行,这可以认为是真正意义上的并行
分布式编程 (Distributed Programming)
分布式编程的模型图如下所示:
分布式编程指在不同机器上同时完成同一项任务,是物理上的隔离。如 Hadoop 中的 MapReduce 就是分布式编程的一个典型例子。
并行化编程的通信方式
由于并行化后的进程要完成的是同一项任务,所以程序间的通信是必须的。程序的通信方式一般有以下两种:共享状态(shared state)、消息传递(message passing)
共享状态(shared state)
这种方法就是共享进程间的资源,类似于同一进程里所有的线程共享进程的资源一样。
这种方法有以下不足:任一进程对共享资源的错误操作都会影响其他的进程;难以应用在分布式编程中。
在这种通信方式下,对于只读的数据可以不加保护措施,但是对于可写的数据,必须要防止多个进程同时修改这个数据。如在操作系统中的互斥量(mutex),线程锁等就是这类型的防护措施。
消息传递(message passing)
消息传递能够避免上面提到的问题,而且也能够应用在分布式编程中。每进行一次消息传递,都会复制一份数据,因此数据的一致性大大提升。
虽然这种方法占用的内存比第一种要大,但是这种方法有以下优势:
- 数据的一致性大大增强
- 消息能够在本地传输(多进程)或者在分布式环境中传输
- 解决可伸缩问题并允许不同系统间的相互操作
- 对于编程人员来说便于实现
并行化编程存在的问题
在并行化编程中有可能会遇到以下问题
死锁 (DeadLock)
与操作系统中的死锁问题一样,发生在多个进程中每个都需要其他进程的资源,同时又不肯释放自己的资源,导致资源的需求关系形成闭合的环状。
如下图所示,进程 A 需要进程 C 的资源,进程 C 需要进程 B 的资源,而进程 B 需要进程 A 的资源。并且在进程释放自己的资源前,其他进程无法获取,而进程需要获得其他进程的资源才能完成自己的任务并释放资源,这样就是一个死锁的局面。
饿死 (Starvation)
饿死概念与操作系统中的也是一样,指的是某个进程一直得不到自己的资源,无法继续运行。
如进程 A 的优先级比 B 要高,所以优先运行 A,但是进程 A 由于需要完成的任务繁重,所以一直占用着 CPU,导致进程 B 一直无法运行,就称为进程 B 被饿死。
竞争条件 (Race conditons)
竞争条件是操作系统和电子电路中的一个常见概念,维基百科对其定义如下:
A race condition or race hazard is the behavior of an electronic, software or other system where the output is dependent on the sequence or timing of other uncontrollable events. It becomes a bug when events do not happen in the order the programmer intended. The term originates with the idea of two signals racing each other to influence the output first.
大意就是多个具有不确定性(无法知道何时会到达或执行指定操作)的对象(进程或电子信号),必须要按照时间序列(time sequence)执行,假如这种同步被破坏,那么多个进程会没有顺序地修改同一个变量,导致数据出错。如下面的简单例子:
假设图中的 husband 和 wife 是两个进程,两者同时操作账户里的钱,正常情况下是这样的
而假如两者不按照 time sequences 执行操作,同步会被破坏,导致出现 race conditions,如下图所示:
python 中实现并行化编程工具
- threading 模块,python 自带的多线程模块
- multiprocessing模块,python 自带的多进程模块
- parallel Python模块,具有运行过程调整进程数目、动态负载平衡的第三方模块
- Celery 模块,用于分布式编程的一个分布式任务队列模块
参考: Parallel Programming with Python