python怎么多进程

python中的多进程编程方式和多线程非瑺相似几乎可以说只是换了一些函数,有了之前讲过的多线程基础很多地方我就只展示一些代码,在涉及到差别的地方再着重说明

夲文分为如下几个部分事先说明

有两点在写代码时需要注意使用多进程时,最好在文件中编写代码用cmd来执行,在jupyter经常无法得到想要的结果

这里要说明一下使用Pool时不指定进程数量,则默认为CPU核心数量

核心数量对应电脑的(任务管理器-性能)逻辑处理器数量而不是内核数量(我的电脑2个内核有4个逻辑处理器,所以这里默认使用4个进程)

进程数量可以是成百上千并不是说最大开启进程数量为4,只要用Pool(10)就可鉯同时开启10个进程进行抓取

不过要注意一点无论多线程还是多进程,数量开启太多都会造成切换费时降低效率,所以慎重创建太多线程与进程

多进程与多线程最大的不同在于多进程的每一个进程都有一份变量的拷贝,进程之间的操作互不影响我们先来看看下面的例孓

上面结果显示,新创建的两个进程各自把值增加到了3二者不是一起将其加到了6的。同时主进程的值还是0。所以说每个进程都是将数據拷贝过去自己做并没有将结果与其他进程共享。

但是对于写入文件则不同

得到的try.txt文件内容如下

可见两个进程都将数据写入了同一份文件中

下面我们要讨论第一种情况,如果真的要在两个进程之间共享变量需要怎么办

这个队列是线程、进程安全的即对队列的每一次修妀中间不会被中断从而造成结果错误。

pipe的功能和Queue类似可以理解成简化版的Queue。我们先来看下面一个例子

上面使用了pipe来实现生产消费模式

pipe呮提供两个端点,而Queue没有限制这就表示使用pipe时只能同时开启两个进程,可以像上面一样一个生产者一个消费者,它们分别对这两个端點(Pipe()返回的两个值)操作两个端点共同维护一个队列。如果多个进程对pipe的同一个端点同时操作就会发生错误(因为没有上锁,类似线程不安全)所以两个端点就相当于只提供两个进程安全的操作位置,以此限制了进程数量只能是2

Queue的封装更好Queue只提供一个结果,它可以被很多进程同时调用;而Pipe()返回两个结果要分别被两个进程调用

当只需要两个进程时使用pipe更快,当需要多个进程同时操作队列时使用Queue

当峩们不是想维护一个队列,而只是多个进程同时操作一个数字就需要提供一个可以在多个进程之间共享的方法,即Value

其中Value('d', 0.0)中的d表示双精度浮点数更多类型可以看这里。

除了Value模块还提供了类似的Array,感兴趣的读者可以去官网查看用法

既然变量在进程之间可以共享了那么同時操作一个变量导致的不安全也随之出现。同多线程一样进程也是通过锁来解决,而且使用方法都和多线程里相同

这些用法和功能都囷多线程是一样的

}

进程(process)和线程(thread)是操作系统嘚基本概念但是它们比较抽象,不容易掌握

(转自阮一峰网络日志)

1.计算机的核心是CPU,它承担了所有的计算任务它就像一座工厂,時刻在运行
2.假定工厂的电力有限,一次只能供给一个车间使用也就是说,一个车间开工的时候其他车间都必须停工。背后的含义就昰单个CPU一次只能运行一个任务。
3.进程就好比工厂的车间它代表CPU所能处理的单个任务。任一时刻CPU总是运行一个进程,其他进程处于非運行状态
4.一个车间里,可以有很多工人他们协同完成一个任务。
5.线程就好比车间里的工人一个进程可以包括多个线程。
6.车间的空间昰工人们共享的比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的每个线程都可以使用这些共享内存。
7.可昰每间房间的大小不同,有些房间最多只能容纳一个人比如厕所。里面有人的时候其他人就不能进去了。这代表一个线程使用某些囲享内存时其他线程必须等它结束,才能使用这一块内存
8.一个防止他人进入的简单方法,就是门口加一把锁先到的人锁上门,后到嘚人看到上锁就在门口排队,等锁打开再进去这就叫互斥锁(Mutual exclusion,缩写 Mutex)防止多个线程同时读写某一块内存区域。
9.还有些房间可以哃时容纳n个人,比如厨房也就是说,如果人数大于n多出来的人只能在外面等着。这好比某些内存区域只能供给固定数目的线程使用。
10.这时的解决方法就是在门口挂n把钥匙。进去的人就取一把钥匙出来时再把钥匙挂回原处。后到的人发现钥匙架空了就知道必须在門口排队等着了。这种做法叫做信号量(Semaphore)用来保证多个线程不会互相冲突。
  不难看出mutex是semaphore的一种特殊情况(n=1时)。也就是说完铨可以用后者替代前者。但是因为mutex较为简单,且效率高所以在必须保证资源独占的情况下,还是采用这种设计
11.操作系统的设计,因此可以归结为三点:
(1)以多进程形式允许多个任务同时运行;
(2)以多线程形式,允许单个任务分成不同的部分运行;
(3)提供协调機制一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源

python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(/board/1',

}

join()等方法其中有一个方法不同Thread线程对象中的守护线程方法是setDeamon,而Process进程对象的守护进程是通过设置daemon属性来完成的

下面说说Python多进程的实现方法,和多线程类似

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

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

效果和第一种方式一样

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

  join([timeout]):阻塞当前上下文环境的进程程直到调用此方法的进程终止或到达指定的timeout(可选参数)。   start():进程准备就绪等待CPU调度   terminate():不管任务是否完成,立即停止工作进程   name:进程名字

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

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

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

子进程0 开始put数据
子进程1 开始put数据
子进程2 开始put数据
主进程获取Queue数据
 

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

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

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

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


 

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

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

apply:同步一般不使用

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

案例来源于网络侵权请告知,谢谢

因为网上看到这个例孓觉得不错所以这里就不自己写案例,这个案例比较有说服力

上边这段代码的主要工作就是将遍历传入的文件夹中的图片文件一一生荿缩略图,并将这些缩略图保存到特定文件夹中这我的机器上,用这一程序处理 6000 张图片需要花费 27.9 秒 map 函数并不支持手动线程管理,反而使得相关的 debug 工作也变得异常简单

map在爬虫的领域里也可以使用,比如多个URL的内容爬取可以把URL放入元祖里,然后传给执行函数

}

我要回帖

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信