@
Python多进程
• 用multiprocessing替代Thread
• multiprocessing库的出现很大程度上是为了弥补thread库因为GIL低效的缺陷。它完整的复制了一套thread所提供的接口方便迁移。唯一的不同就是它使用了多进程而不是多线程。每个进程有自己的独立的GIL,完全并行,无GIL的限制(进程中包括线程),可充分利用多cpu多核的环境,因此也不会出现进程之间的GIL争抢。
• python多进程并发,模块名称:multiprocessing
• python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。
• 借助这个包,可以轻松完成从单进程到并发执行的转换。
• 导入方式: import multiprocessing
Multiprocessing使用简介-1
• multiprocessing包是Python中的多进程管理包。与threading.Thread类似,它可以利用multiprocessing.Process对象来创建一个进程。该Process对象与Thread对象的用法相同,也有start(), run(), join()等方法。
• 此外multiprocessing包中也有Lock/Event/Semaphore/Condition类 (这些对象可以像多线程那样,通过参数传递给各个进程),用以同步进程,其用法与threading包中的Thread类一致。所以,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境。
• multiprocessing提供了threading包中没有的IPC(比如Pipe和Queue),效率上更高。应优先考虑Pipe和Queue,避免使用Lock/Event/Semaphore/Condition等同步方式 (因为它们占据的不是用户进程的资源,而是线程)。
Process
创建进程的类:Process([group [, target [, name [, args [, kwargs]]]]])
方法:is_alive()、join([timeout])、run()、start() 。其中,Process以start()启动某个进程。
多进程的几种方法
• Lock:可以避免访问资源时的冲突
• Pool:可以提供指定数量的进程
• Queue:多进程安全的队列,实现多进程之间的数据传递
• Pipe:实现管道模式下的消息发送与接收
Lock
同步执行:一个进程在执行任务时,另一个进程必须等待执行完毕,才能继续执行,加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改.没错,速度是慢了,但牺牲了速度却保证了数据安全。
异步执行:一个进程在执行任务时,另一个进程无需等待其执行完毕就可以执行,当有消息返回时,系统会提醒后者进行处理,这样会很好的提高运行效率.
Pool
Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来执行它。
进程池方法:
apply(func[, args[, kwds]]): 阻塞的执行,比如创建一个有3个线程的线程池,当执行时是创建完一个,执行完函数再创建另一个,变成一个线性的执行. apply_async(func[, args[, kwds[, callback]]]) : 它是非阻塞执行,同时创建3个线程的线城池,同时执行,只要有一个执行完立刻放回池子待下一个执行,并行的执行 .
close(): 关闭pool,使其不在接受新的任务。
terminate() : 结束工作进程,不在处理未完成的任务。
join(): 主进程阻塞,等待子进程的退出, join方法要在close或terminate之后使用。
Queue
进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列Queue和管道Pipe,这两种方式都是使用消息传递的
• 创建队列的类(底层就是以管道和锁定的方式实现):
Queue([maxsize]):创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。
参数介绍:maxsize是队列中允许最大项数,省略则无大小限制。
• q.put方法用以插入数据到队列中,
put方法还有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间。如果超时,会抛出Queue.Full异常。如果blocked为False,但该Queue已满,会立即抛出Queue.Full异常。
• q.get方法可以从队列读取并且删除一个元素。
同样,get方法有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,那么在等待时间内没有取到任何元素,会抛出Queue.Empty异常。如果blocked为False,有两种情况存在,如果Queue有一个值可用,则立即返回该值,否则,如果队列为空,则立即抛出Queue.Empty异常。
• q.get_nowait():同q.get(False)
• q.put_nowait():同q.put(False)
• q.empty():调用此方法时q为空则返回True,该结果不可靠,比如在返回True的过程中,如果队列中又加入了项目。
• q.full():调用此方法时q已满则返回True,该结果不可靠,比如在返回True的过程中,如果队列中的项目被取走。
• q.qsize():返回队列中目前项目的正确数量,结果也不可靠,理由同上.
Python—队列、生产者消费者模型
1、queue.Queue是进程内非阻塞队列
2、multiprocess.Queue是跨进程通信队列
• 队列:FIFO(先进先出)、LIFO(后进先出)