一、进程:是指一个具有独立功能的程序的一次执行过程。

  1、进程单独分配内存空间,占用资源较多,不是越多越好;

  2、一个进程中可以含有多个线程并发执行,但python中规定一个进程只允许一个线程与CPU交互;

  3、为提高效率,一个进程最好对应一个CPU,所以多进程适用于计算密集型的程序;

  二、进程模块:multiprocessing

  与多线程threading模块类似,通过生成Process对象,然后start执行多线程

  (一)创建进程

from multiprocessing import Process

def f(name):
    print('hello',name)

if __name__ == '__main__':
    p = Process(target=f,args=('bob',))
    p.start()
    p.join()
View Code

  (二)前台进程与后台进程

  使用 deamon 或者 join 控制主进程是否、如何等待子进程结束。

from multiprocessing import Process
import time

def f(name):
    time.sleep(1)
    print('hello',name)

if __name__ == '__main__':
    p = Process(target=f,args=('bob',))
    p.daemon = True  # 设置为后台进程
    p.start()
    # p.join()  # 不限时等待进程结束
View Code

  (三)进程间的数据共享

  通常情况下,由于不同进程分别占用不同的内存空间,所以数据之间不共享。

  如果需要进程之间数据共享,可以使用如下两种方式:

  1、方式一:内存共享

  将数据使用Value或者Array储存在一个共享的内存地图里,Array和Value必须确定大小、统一数据类型。

from multiprocessing import Process,Value,Array

def func(n,a):
    n.value = 3.14
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == '__main__':
    n = Value('d',0.0)
    a = Array('i',range(10))
    # ‘d'表示一个双精度的浮点数,'i'表示一个有符号的整数
    f = Process(target=func,args=(n,a,))
    g = Process(target=func,args=(n,a,))
    f.start()
    g.start()
    f.join()
    g.join()

    print(n.value)
    print(a[:])
View Code

  2、方式二:server process

  使用manager提供支持的dict、list等类型数据。

from multiprocessing import Process,Manager

def func(d,l):
    d[0] = '2'
    d['ji'] = None
    l.reverse()

if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict()
        l = manager.list(range(10))

        p =Process(target=func,args=(d,l))
        p.start()
        p.join()

        print(d)
        print(l)
View Code

  (四)进程池 Pool

  python进程池提供两种方法:apply 和 apply_async:

  apply:不支持回调函数;内部join,一个一个执行;  

  apply_async:支持回调函数;内部异步并发,且默认后台进程,需要等待子进程结束需使用join。

# 进程池Pool:apply 与 applu_async
from multiprocessing import Pool
import time

# .apply : 每个进程自身带有.join方法,进程之间排队执行,执行完一个才能开始另一个
# .apply直接返回该进程所执行的函数结果,不使用回调函数。

def f(a):
    time.sleep(1)
    print('f:',a)
    return a

if __name__ == '__main__':
    pool = Pool(4)
    for i in range(12):
        ret = pool.apply(func=f,args=(i,))
        print('pool.apply:',ret)


# .apply_async :各进程内不含.join方法,进程之间异步并发,且都默认为后台进程,
# .apply_async : 不能直接返回进程函数的返回值,需要使用回调函数。

def f(a):
    time.sleep(1)
    print('f:',a)
    return a

def g(args):
    print('callback:',args)

if __name__ == '__main__':
    pool = Pool(4)
    for i in range(12):
        ret = pool.apply_async(func=f,args=(i,),callback=g)
        print('pool.apply_async:',ret)

    # 为显示结果,使用如下方式可将后台进程改成前台进程
    pool.close()
    pool.join()
    
    # 需要立即终止进程时:
    pool.terminate()
    
View Code