Python 2.x 中如何使用multiprocessing模块进行多进程管理

1. 前言

在Python编程过程中,经常需要多进程或多线程来实现并发。与多线程相比,多进程在Python中更加强大和安全,可以通过操作系统的进程管理实现运算分离、资源隔离等,从而提高程序的稳定性。

Python自带了multiprocessing模块,使得并行编程更加简洁。

2. multiprocessing模块概述

Python的multiprocessing模块提供了一个 Process 类来代表一个进程对象。

2.1 Process类

每个进程都被封装在一个 Process 实例中。Process 类具有很多方法和属性。如果要定义一个新的进程,必须继承 Process 并实现其 run() 方法。其中run() 方法定义了进程的活动,它是一个必须实现的方法。

from multiprocessing import Process

def f(name):

print('hello', name)

if __name__ == '__main__':

p = Process(target=f, args=('Bob',))

p.start()

p.join()

注意:在Windows系统下,由于没有fork调用,可以参考如下方法实现进程的创建:

from multiprocessing import Process, Value, Array

def f(n, a):

n.value = 3.1415927

for i in range(len(a)):

a[i] *= 2

if __name__ == '__main__':

num = Value('d', 0.0)

arr = Array('i', range(10))

p = Process(target=f, args=(num, arr))

p.start()

p.join()

print(num.value)

print(arr[:]

2.2 Pool类

Pool类提供了一个process类的简单方式,来批处理任务3。

from multiprocessing import Pool

import time

def f(x):

time.sleep(2)

return x*x

if __name__ == '__main__':

with Pool(5) as p:

print(p.map(f, [1, 2, 3]))

3. multiprocessing模块使用示例

下面以一个简单的示例演示如何使用multiprocessing模块实现多进程管理。

需求:计算0~10000之间的素数。采用多进程方式,将数字拆分成两个部分,每部分交由一个进程计算素数,最后将结果合并。

3.1 单进程版代码

首先是单进程版的代码,使用循环计算从0到10000之间的素数:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

import math

import time

def is_prime(number):

"""

判断一个数是否为素数。

:param number: 待判断的数。

:return: 如果number是素数,返回True;否则,返回False。

"""

for i in range(2, int(math.sqrt(number) + 1)):

if number % i == 0:

return False

return True

if __name__ == '__main__':

start = time.time()

primes = []

for number in range(1, 10000):

if is_prime(number):

primes.append(number)

print(len(primes))

end = time.time()

print('Elapsed time: {} s'.format(end - start))

注意:如果在Windows下运行上面的代码会出现如下问题:

AttributeError: module 'math' has no attribute 'sqrt'

这是因为Windows下使用的Python解释器是通过freeglut库实现的,它没有math库的内容。所以,如果你在Windows下使用Python,只需要改变头文件的引入方式即可。将代码中的:

import math

改成:

from math import sqrt

然后,将用到`sqrt()`的代码修改成:

for i in range(2, int(sqrt(number) + 1)):

if number % i == 0:

return False

3.2 多进程版代码

现在,我们来看看如何使用multiprocessing模块,将程序改为支持多进程计算。

将一个计算任务划分成若干份,每部分采用不同的进程计算,最后再将结果合并。

#!/usr/bin/python

# -*- coding: UTF-8 -*-

import math

import multiprocessing

import time

def is_prime(number):

"""

判断一个数是否为素数。

:param number: 待判断的数。

:return: 如果number是素数,返回True;否则,返回False。

"""

for i in range(2, int(math.sqrt(number) + 1)):

if number % i == 0:

return False

return True

def calc(start, end):

primes = []

for number in range(start, end):

if is_prime(number):

primes.append(number)

return primes

if __name__ == '__main__':

start = time.time()

pool = multiprocessing.Pool(processes=4)

results = []

for i in range(4):

start_num = i * 2500

end_num = start_num + 2500

results.append(pool.apply_async(calc, (start_num, end_num)))

pool.close()

pool.join()

primes = []

for result in results:

primes += result.get()

print(len(primes))

end = time.time()

print('Elapsed time: {} s'.format(end - start))

在这个代码中,我们首先创建了一个包含4个进程的进程池,然后将计算任务0~10000划分成了$4\times2500$个部分。接着将运算任务交由进程池的4个进程并行计算。最后,将每个进程的结果合并成最终结果输出。

可以看出,多进程版的代码执行效率要高于单进程版,这是因为多进程可以并行计算,充分利用了系统资源。

4. 总结

本文介绍了如何使用Python的multiprocessing模块实现多进程管理,以及如何将单进程程序改为支持多进程计算的程序。通过这些示例,我们可以学习到如何使用Python的multiprocessing模块。同时,也可以在实际应用中,通过使用多进程技术来提高程序的执行效率。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

后端开发标签