Python 进程池

当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态成生多个进程,但如果是上百甚至上千个目标,手动的去创建进程的工作量巨大,此时就可以用到multiprocessing模块提供的Pool方法。

初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,直到池中有进程结束,才会用之前的进程来执行新的任务。

1、创建进程池

例:创建进程池

创建进程池时,需要导入multiprocessing模块中的Pool类

如上图所示,我们利用Pool()类创建了一个容量为3的进程池,并且利用apply_saync()方法向进程池中添加了10次任务,该方法第一个参数接收一个函数名,进程池中的进程会执行这个函数中的程序,第二个参数是一个元组类型,表示调用的函数的参数。但是此时,程序并不会运行,因为当前状态下,向进程池添加了任务后,主程序就退出了,主程序不会等待所有进程结束就会自动结束。因此需要调用进程池的其他方法。

调用close()方法,关闭进程池,关闭后po不再接收新的请求。

调用join()方法,等待pool中所有子进程执行完成,必须放在close语句之后

当向进程池添加的任务多于进程池初始化的进程数时,不会导致堵塞,多余的任务会排队等待,直到有空闲进程去执行这个任务

multiprocessing.Pool常用函数解析:

apply_async(func[, args[, kwds]]) :使用非阻塞方式调用func(并行执行,堵塞方式必须等待上一个进程退出才能执行下一个进程),args为传递给func的参数列表,kwds为传递给func的关键字参数列表;

close():关闭Pool,使其不再接受新的任务;

terminate():不管任务是否完成,立即终止;

join():主进程阻塞,等待子进程的退出, 必须在close或terminate之后使用;

2、进程间通信

虽然可以利用Process()、Pool()创建不同数量进程,但是进程之间都是相互独立的。要想做到进程之间互相通信,就需要借助第三方,我们利用Queue类作为进程之间通信的媒介。

例:Queue的基本使用

队列(queue)特点是先进先出(First in First out)。在队列中涉及到这样的几个操作:入队(把数据添加到队尾)、出队(从队首取出一个数据)、队列初始化(创建一个队列)、销毁一个队列(把整个队列的数据从内存中删除)、判断队列是否为空、判断队列是否满、获取队列的长度。

队列对象的方法:

Queue.qsize() :返回queue的近似值。注意:qsize>0 不保证(get)取元素不阻塞。qsize< maxsize不保证(put)存元素不会阻塞

Queue.empty():判断队列是否为空。和上面一样注意

Queue.full():判断是否满了。和上面一样注意

Queue.put(item,block=True,timeout=None): 往队列里放数据。如果满了的话,blocking = False 直接报 Full异常。如果blocking = True,就是等一会,timeout必须为 0 或正数。None为一直等下去,0为不等,正数n为等待n秒还不能存入,报Full异常。

 Queue.put_nowait(item):往队列里存放元素,不等待

Queue.get(item,block=True,timeout=None): 从队列里取数据。如果为空的话,blocking = False 直接报 empty异常。如果blocking = True,就是等一会,timeout必须为 0 或正数。None为一直等下去,0为不等,正数n为等待n秒还不能读取,报empty异常。

 Queue.get_nowait(item):从队列里取元素,不等待

例:利用Queue实现进程间通信

如果要使用Pool创建进程,就需要使用multiprocessing.Manager()中的Queue(),而不是multiprocessing.Queue(),否则会得到一条如下的错误信息:

RuntimeError: Queue objects should only be shared between processes through inheritance.

例:进程池使用Queue进行通信

你可能感兴趣的:(Python 进程池)