这是我参与「第四届青训营」笔记创作活动的第11天。
1进程(Process)
是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。多进程就是启用多个进程同时运行。由于进程中GIL的存在。
Python中的多线程并不能很好地发挥多核优势,一个进程中的多个线程,同一时刻只能有一个线程运行。
对于多进程来说,每个进程都有属于自己的GIL所以在多核处理器下,多进程的运行是不会受GlL的影响的。因此多进程能更好地发挥多核的优势。
Python的多进程整体来看是比多线程更有优势,在条件允许的情况下,能用多进程就尽量用多进程。由于进程是系统进行资源分配和调度的一个独立单位,所以各个进程之间的数据是无法共享的。
2多进程的基本实现
2.1直接使用Process类
在multiprocessing中,每进程都用一个Process类来表示。
API调用:Process([group[,target[,name[,args[,kwargs]]])
target表示调用对象,你可以传入方法的名字
args表示被调用对象的位置参数元组。比如target是函数func,他有两个参数m,n,那么args就传入(m,n)即可。如果是一个m,则传入(m,),因为必须传入元组。
kwargs 表示调用对象的字典
name是别名,相当于给这个进程取一个名字
group分组
multiprocessing还提供了几个比较有用的方法:通过cpu_count方法来获取当前机器CPU的核心数量;通过active_children方法获取当前还在运行的所有进程。
2.2继承Process类
创建进程也可以像线程Thread一样,通过继承的方式创建一个进程类。 进程的基本操作在子类的run方法中实现即可。
2.3守护进程
如果一个进程被设置为守护进程,当父进程结束后,子进程会自动被终。可以通过设置 daemon属性,来控制是否为守护进程。
2.4进程等待
让所有子进程都执行完了然后再结束。只需要加入join方法即可。
2.5终止进程
终止进程不止有守护进程这一种做法,可以通过terminate方法来终止某个子进程,还可以通过is_alive 方法判断进程是否还在运行。
3进程的更多实现
3.1进程互斥锁
如果能保证多个进程运行期间的任一时间,只能一个进程输出,其他进程等待。等刚才那个进程输出完毕之后,另一个进程再进行输出,就不会出现输出没有换行的现象。
3.2信号量
信号量是进程同步过程中一个比较重要的角色可以控制临界资源的数量 实现多个进程同时访问共享资源,限制进程的并发量可以用multiprocessing库中的Semaphore来实现信号量
3.3队列
队列可以让进程共享数据。使用multiprocessing里面的Queue完成。
3.4管道
可以理解为两个进程之间通信的通道。
可以是单向的,即half-duplex:一个进程负责发消息,另一个进程负责收消息。也可以是双向的duplex,即互相收发消息。
默认声明Pipe对象是双向管道。如果要创建单向管道,可以在初始化的时候传入deplex参数为False。
3.5进程池
假如有10000个任务,每个任务需要启动一个进程来执行,并且一个进程运行完毕之后要紧接着启动下一个进程,同时还需要控制进程的并发数量,不能并发太高,不然CPU处理不过来(如果同时运行的进程能维持在一个最高恒定值,利用率当然是最高的)
进程池即multiprocessing中的Pool,可以提供指定数量的进程,供用户调用。
当有新的请求提交到pool中时,如果池还没有满,就会创建一个新的进程用来执行该请求;如果池中进程数已达到规定最大值,那么该请求就会等待直到池中有进程结束,才会创建新的进程来执行它。
map方法的使用:第1个参数就是要启动的进程对应的执行方法;第2个参数是一个可迭代对象,其中的每个元素会被传递给第1个参数对应的执行方法。
个人总结
这篇文章重点介绍了如何使用multiprocessing模块实现多进程,以及什么是守护进程,如何进行进程等待,什么是进程互斥锁、信号量,队列和管道的作用。