Python 3 多进程

2019-10-16 11:39:32 浏览数 (1)

什么是进程


进程指的是正在进行的一个过程或者一个任务,而执行这个任务的是CPU。进程与程序的区别,可以理解为程序是我们写的一堆代码,而进程则是CPU执行这堆代码的过程,同一个程序被执行两次,就会产生两个进程。凡是硬件,都需要有操作系统进行管理,只要是操作系统,就会有进程概念,需要有创建进程的方式。进程的三种状态:

运行态:应用程序正在被CPU执行中

阻塞态:当前进程突然要做I/O操作,然后CPU去执行其他的程序

就绪态:时刻准备着能够被执行

Python 实现多进程


在Python中实现多进程有两种方式:一种是使用os模块中的fork方法,另一种是使用multiprocessing模块。两者的区别在于,fork仅适用于Unix/Linux操作系统中,对于Windows不支持,而multiprocessing则是跨平台的实现方式。

使用multiprocessing创建多进程

multiprocessing模块提供了一个Process类来描述一个进程对象(需了解面向对象编程知识点)。创建子进程时,只需要传入一个执行函数和函数的参数,就可完成一个Process实例创建,用start()方法启动进程,用join()方法进行进程间的同步。

代码语言:javascript复制
import os,time
from multiprocessing import Process
#子进程要执行的函数
def proc_run(pid):
    print('进程 %s (Pid:%s) 运行,进程生成时间:'%(pid,os.getpid()),time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) )
#程序入口
if __name__=='__main__':
    print('当前进程ID:%s'%os.getpid())
    for i in range(5):
        p = Process(target=proc_run,args=(i,))
        print('子进%s程启动'%i)
        p.start()
    p.join()
    print('进程结束!')      

IDE运行结果如下:

仔细观察,上面IDE窗口中打印的东西貌似没有创建的5个子进程proc_run函数中的执行内容,windows中的小坑之一,IDE输出窗口输出的主进程的内容,我们创建的进程p不是主进程,当然无输出。想要看到输出结果,要在cmd下运行python脚本,命令为:“python 脚本.py ”:

进程池运用


上面介绍了用multiprocessing中的Process类动态生成多个进程,如果要创建上百个,上千个目标,手动限制进程数量太过繁琐,这种情形下我们可以通过进程池Pool来解决。

Pool可提供指定数量的进程供用户进行调用,默认进程数是CPU的核数。当有新的请求提交到Pool中时,如果资源池还没满,就会创建一个新的进程,如果Pool中的进程数达到最大值,新的请求就会进入等待状态,直到进程池中有进程结束,才会创建新的进程来处理。

代码语言:javascript复制
import os,time,random
from multiprocessing import Pool
def pool_run(pid):
    print('进程 %s (Pid:%s) 运行,进程生成时间:'%(pid,os.getpid()),time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) )
    time.sleep(random.random()*3)
    print('进程 %s 运行结束'%id)

if __name__=='__main__':
    print('当前进程ID:%s'%os.getpid())
    p=Pool(processes=3)
    for i in range(5):
        p.apply_async(pool_run,args=(i,))
    print('子进%s程启动'%i)
    p.close()
    p.join()
    print('进程结束!')

运行结果如下:

上面的代码创建了容量为3的进程池,再向进程池中添加5个任务,从运行结果可看出,虽然是创建5个进程任务,但每次最多运行3个,当一个任务结束了,新的任务才被添加进来,而新添加的任务依然是原来的进程,从进程的pid可以看出。

注意事项:Pool对象调用join()方法会等待所有子进程执行完成,调用join()之前必须先调用close(),调用了close()方法后就不能继续添加新的Process。


0 人点赞