1.前言在Thread和Process中,Process应该是首选,因为Process更稳定,Process可以分布到多台机器上,而Thread最多只能分布到同一台机器上的多个CPU。Python的multiprocessing模块不仅支持多进程,managers子模块也支持将多个进程分布到多台机器上。可以写一个服务进程作为调度器,将任务分发给其他进程,依靠网络通信进行管理。2.案例分析在做爬虫程序的时候,抓取某个网站的所有图片。如果使用多进程,一般一个进程负责抓取图片的链接地址,将链接地址放入队列,另一个进程负责抓取图片的链接地址。队列中的链接地址被下载并保存在本地。如何使用分布式流程来实现?一台机器上的进程负责抓取链接地址,其他机器上的进程负责存储。那么遇到的主要问题就是将队列暴露在网络中,让其他机器进程可以访问。分布式进程封装了这个过程。这个过程可以称为本地队列的组网。例:1.pyfrommultiprocessing.managersimportBaseManagerfrommultiprocessingimportfreeze_support,Queue#任务个数task_number=10#收发队列task_quue=Queue(task_number)result_queue=Queue(task_number)defget_task():returntask_quuedefget_result():returnresult_queue#创建类似的queueManagerclassQueueManager(BaseManager):passdefwin_run():#在网络上注册,callable与Queue对象关联#ExposeQueue对象在网络上#window下的绑定调用接口不能直接使用lambda,只能先定义函数再绑定QueueManager。register('get_task_queue',callable=get_task)QueueManager.register('get_result_queue',callable=get_result)#绑定端口和设置认证密码manager=QueueManager(address=('127.0.0.1',8001),authkey='qiye'.encode())#开始管理,监听信息通道manager.start()try:#通过网络获取任务队列和结果队列task=manager.get_task_queue()result=manager.get_result_queue()#为urlin添加任务["imageUrl_"+str(i)foriinrange(10)]:print('urlis%s'%url)task.put(url)print('trygetresult')foriinrange(10):print('resultis%s'%result.get(timeout=10))except:print('Managererror')finally:manager.shutdown()if__name__=='__main__':freeze_supportt()win_run()连接服务器,端口和验证密码与服务器进程中保持完全一致从网络获取Queue,进行本地化,从任务队列中获取任务,将结果写入到resultqueue2.py#coding:utf-8importtimefrommultiprocessing.managersimportBaseManager#创建一个类似Manager:classManager(BaseManager):pass#使用QueueManager注册获取QueueManager.register('get_task_queue')Manager.register('的方法名get_result_queue')#连接服务器:server_addr='127.0.0.1'print('Connecttoserver%s...'%server_addr)#端口和验证密码要和服务进程设置的完全一致:m=Manager(address=(server_addr,8001),authkey='qiye')#从网络连接:m.connect()#获取Queue对象:task=m.get_task_queue()result=m.get_result_queue()#获取从任务队列中取出任务并将结果写入结果队列:while(nottask.empty()):image_url=task.get(True,timeout=5)print('runtaskdownload%s...'%image_url)time.sleep(1)result.put('%s--->success'%image_url)#End:print('workerexit.')任务进程需要通过网络连接到服务进程,所以需要指定服务进程的IP。运行结果如下:获取图片地址,并将地址传给2.py。接收1.py传过来的地址,下载图片,控制台会显示爬取结果。3.总结本文是基于Python的基础。Python的分布式进程接口简单,封装性好,适用于需要将繁重的任务分发到多台机器的环境。通过说明Queue的作用是传递任务和接收结果。欢迎大家积极尝试。有时候看别人实现很简单,但是到了自己实现的时候,总会出现各种各样的问题。不要野心太大,努力理解得更深刻。
