Python多进程multiprocessing(二)

紧接上文

在上文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]

解释一下:

  1. 这个例子演示了进程池pool的用法,创建Pool对象并指定使用2个核(默认使用全部)。
  2. 之前我们定义任务的时候是不能有return的,pool的map方法可以将任务依次作用到数据上去。
  3. 另一个类似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])

解释一下:

  1. 这里展示了两种共享内存的形式,一个是Value,一个是Array(其实就是list)
  2. 要注意的是,在定义值的同时需要指定数值类型,比如整型"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

解释一下:

  1. 这就是使用共享内存的作用,两次任务执行是累加的
  2. 在调用共享内存值的时候需要使用.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

解释一下:

  1. 这里演示了Lock的使用,其实用法与多线程的lock一样,也是使用acquire和release方法来控制。
  2. 注意,需要把lock对象作为参数一起传入process里。

小结

多进程multiprocessing的部分就到这里,再加上之前分享的多线程threading,大家应该有了一些直观的印象,什么时候使用多线程多进程,以及使用哪一个还是一起使用都是要看具体任务的。那么,剩下的就是去实际操作了,踩坑填坑,熟练掌握!

posted @ 2019-12-31 16:58  MrDoghead  阅读(216)  评论(0编辑  收藏  举报