51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Python 多进程

本文介绍Python多进程模块。

概述 {#概述}

Python中的多进程是通过multiprocessing包来实现的,和多线程的threading.Thread差不多,它可以利用multiprocessing.Process对象来创建一个进程对象。这个进程对象的方法和线程对象的方法差不多也有start(), run(), join()等方法,其中有一个方法不同Thread线程对象中的守护线程方法是setDeamon,而Process进程对象的守护进程是通过设置deamon属性来完成的。

Python多进程实现 {#Python多进程实现}

方法一 {#方法一}

结果

上面的代码开启了5个子进程去执行函数,我们可以观察结果,是同时打印的,这里实现了真正的并行操作,就是多个CPU同时执行任务。我们知道进程是python中最小的资源分配单元,也就是进程中间的数据,内存是不共享的,每启动一个进程,都要独立分配资源和拷贝访问的数据,所以进程的启动和销毁的代价是比较大了,所以在实际中使用多进程,要根据服务器的配置来设定。

方法二 {#方法二}

还记得python多线程的第二种实现方法吗?是通过类继承的方法来实现的,python多进程的第二种实现方式也是一样的

结果

效果和第一种方式一样。

我们可以看到Python多进程的实现方式和多线程的实现方式几乎一样。

Process类的其他方法 {#Process类的其他方法}

关于join,daemon的使用和python多线程一样,这里就不在复述了,大家可以看看以前的python多线程系列文章。

Python多线程的通信 {#Python多线程的通信}

进程是系统独立调度核分配系统资源(CPU、内存)的基本单位,进程之间是相互独立的,每启动一个新的进程相当于把数据进行了一次克隆,子进程里的数据修改无法影响到主进程中的数据,不同子进程之间的数据也不能共享,这是多进程在使用中与多线程最明显的区别。但是难道Python多进程中间难道就是孤立的吗?当然不是,python也提供了多种方法实现了多进程中间的通信和数据共享(可以修改一份数据)

进程队列Queue {#进程队列Queue}

Queue在多线程中也说到过,在生成者消费者模式中使用,是线程安全的,是生产者和消费者中间的数据管道,那在python多进程中,它其实就是进程之间的数据管道,实现进程通信。

结果

上面的代码结果可以看到我们主进程中可以通过Queue获取子进程中put的数据,实现进程间的通信。

管道Pipe {#管道Pipe}

管道Pipe和Queue的作用大致差不多,也是实现进程间的通信,下面之间看怎么使用吧

结果

上面可以看到主进程和子进程可以相互发送消息

Managers {#Managers}

Queue和Pipe只是实现了数据交互,并没实现数据共享,即一个进程去更改另一个进程的数据。那么久要用到Managers

结果:

可以看到主进程定义了一个字典和一个列表,在子进程中,可以添加和修改字典的内容,在列表中插入新的数据,实现进程间的数据共享,即可以共同修改同一份数据

进程锁 {#进程锁}

在多进程程序运行时,可能会有部分内存或硬盘可以同时被多个进程操作,如果不小心管理很可能导致冲突。此时可以用进程锁有效解决问题。

进程池 {#进程池}

进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。就是固定有几个进程可以使用。

常规进程池 {#常规进程池}

进程池中有两个方法:

apply:同步,一般不使用

apply_async:异步

结果

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

进程池map方法 {#进程池map方法}

上边这段代码的主要工作就是将遍历传入的文件夹中的图片文件,一一生成缩略图,并将这些缩略图保存到特定文件夹中。 map 函数并不支持手动线程管理,反而使得相关的 debug 工作也变得异常简单。

多进程启动方式 {#多进程启动方式}

multiprocessing 支持三种方式 启动进程

  • 在python中可以显示设置启动方式

spawn {#spawn}

父进程启动一个新的python解释器进程.子进程只继承运行 Run()方法所需的资源。
来自父进程的不必要的文件描述符和句柄将不会被继承,运行速度比较慢

适用系统:unix and windows

fork {#fork}

父进程使用os.fork()方法对Python解释器进行fork。子进程开始时实际上与父进程相同。
父进程的所有资源都由子进程继承。请注意,安全的fork多线程的进程是有问题的。

适用系统:unix

forkserver {#forkserver}

当程序启动并选择forkserver的启动方法时,将启动服务器进程。
从那时起,每当需要一个新进程时,父进程就会连接到服务器,并请求它fork一个新进程。
fork server进程是单线程的,所以使用os.fork()是安全的。没有任何不必要的资源被继承

适用系统:unix

参考资料 {#参考资料}



文章链接:
https://www.zywvvd.com/notes/coding/python/multi-processing/multi-processing/

赞(0)
未经允许不得转载:工具盒子 » Python 多进程