紧接上文
在上文Python多进程multiprocessing(一)中我们介绍了多进程multiprocessing的部分基础操作,在本文中,我们将继续介绍关于多进程的一些知识,比如进程池Pool这个有用的东东。马上开始吧!
使用实例
实例1
import multiprocessing as mp
def job(x):
return x*x
def multicore():
pool = mp.Pool(processes=2)
res = pool.map(job,range(10))
print(\'map res:\',res)
multi_res = [pool.apply_async(job,(i,)) for i in range(10)]
print(\'apply_async res:\',[res.get() for res in multi_res])
if __name__ == \'__main__\':
multicore()
运行结果:
map res: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
apply_async res: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
解释一下:
- 这个例子演示了进程池pool的用法,创建Pool对象并指定使用2个核(默认使用全部)。
- 之前我们定义任务的时候是不能有return的,pool的map方法可以将任务依次作用到数据上去。
- 另一个类似map的方法是apply_async,但是注意这里传入的参数需要是可迭代的。
实例2
在多线程threading中,我们可以使用global全局变量来共享某个变量,但是在多进程中这是行不通的,我们需要用到共享内存shared memory的形式,具体做法如下:
import multiprocessing as mp
value = mp.Value(\'d\', 3.14)
array = mp.Array(\'i\', [1,2,3])
解释一下:
- 这里展示了两种共享内存的形式,一个是Value,一个是Array(其实就是list)
- 要注意的是,在定义值的同时需要指定数值类型,比如整型"i",双浮点型"d",详细的见下表:
Type code | C Type | Python Type | Minimum size in bytes |
---|---|---|---|
\'b\' | signed char | int | 1 |
\'B\' | unsigned char | int | 1 |
\'u\' | Py_UNICODE | Unicode character | 2 |
\'h\' | signed short | int | 2 |
\'H\' | unsigned short | int | 2 |
\'i\' | signed int | int | 2 |
\'I\' | unsigned int | int | 2 |
\'l\' | signed long | int | 4 |
\'L\' | unsigned long | int | 4 |
\'q\' | signed long long | int | 8 |
\'Q\' | unsigned long long | int | 8 |
\'f\' | float | float | 4 |
\'d\' | double | float | 8 |
实例3
import multiprocessing as mp
def job(v,num):
v.value += num
print(v.value)
def multicore():
v = mp.Value(\'i\', 0)
p1 = mp.Process(target=job,args=(v,1))
p2 = mp.Process(target=job,args=(v,10))
p1.start()
p2.start()
p1.join()
p2.join()
if __name__ == \'__main__\':
multicore()
运行结果:
1
11
解释一下:
- 这就是使用共享内存的作用,两次任务执行是累加的
- 在调用共享内存值的时候需要使用.value
实例4
import multiprocessing as mp
def job(v,num,l):
l.acquire()
for i in range(10):
v.value += num
print(v.value)
l.release()
def multicore():
l = mp.Lock()
v = mp.Value(\'i\', 0)
p1 = mp.Process(target=job,args=(v,1,l))
p2 = mp.Process(target=job,args=(v,10,l))
p1.start()
p2.start()
p1.join()
p2.join()
if __name__ == \'__main__\':
multicore()
运行结果:
1
2
3
4
5
6
7
8
9
10
20
30
40
50
60
70
80
90
100
110
解释一下:
- 这里演示了Lock的使用,其实用法与多线程的lock一样,也是使用acquire和release方法来控制。
- 注意,需要把lock对象作为参数一起传入process里。
小结
多进程multiprocessing的部分就到这里,再加上之前分享的多线程threading,大家应该有了一些直观的印象,什么时候使用多线程多进程,以及使用哪一个还是一起使用都是要看具体任务的。那么,剩下的就是去实际操作了,踩坑填坑,熟练掌握!