当前位置: 首页 > 后端技术 > Python

Python多进程+协程的一个例子

时间:2023-03-25 22:15:56 Python

为什么要多进程+协程?因为这样可以达到极高的性能,所以建议先通读Python黑魔法---异步IO(asyncio)协程。话不多说,我们上代码。importasyncioimportmultiprocessingimportosimporttimefrommultiprocessingimportManager#业务类classBaiJiaHao():asyncdefget_author(self,rec):"""协程代码"""print('entergetauthor,waitfor:%d'%rec['num'])#模拟IO操作,耗时根据传入的num决定awaitasyncio.sleep(rec['num'])#协程任务完成后返回结果returnrecdefrun(self):#假设我们有11个任务要运行,每个任务需要num秒,串行需要43秒。#但我们只需要在运行此演示后最多执行这些任务:8秒list=[{'title':'title1','num':2},{'title':'title2','num':1},{'title':'title3','num':3},{'title':'title4','num':8},{'title':'title5','num':2},{'title':'title6','num':5},{'title':'title7','num':7},{'title':'title8','num':3},{'title':'title9','num':4},{'title':'title10','num':3},{'title':'title11','num':5},]result=run_get_author_in_multi_process(list)print('result',result)defget_chunks(iterable,chunks=1):"""这个函数用来把几个任务分到不同的进程中"""lst=list(iterable)return[lst[i::chunks]foriinrange(chunks)]defrun_get_author(lists,queue):"""这是子进程运行的函数,接收任务列表和Queue进行进程间通信"""print('execrun_get_author.childprocessid:%s,parentprocessid:%s'%(os.getpid(),os.getppid()))#为每个子进程分配一个新的循环loop=asyncio.new_event_loop()#初始化业务类并将其变成任务或未来的spider=BaiJiaHao()tasks=[loop.create_task(spider.get_author(rec))forrecinlists]#协程启动loop.run_until_complete(asyncio.wait(tasks))#将每个任务的结果写入队列fortaskintasks:queue.put(task.result())defrun_get_author_in_multi_process(task_lists):"""父进程函数,主要是划分任务和初始化进程池,启动进程并返回结果"""#process_count=len(tasks)%2#Thenumberofprocesses这里我用的是机器上的核数,注意:核数多于任务数的情况不考虑process_count=multiprocessing.cpu_count()print('process_count:%d'%process_count)split_lists=get_chunks(task_lists,process_count)pool=multiprocessing.Pool(process_count)queue=Manager().Queue()forlistsinsplit_lists:pool.apply_async(run_get_author,args=(lists,queue,))pool.close()pool.join()result=[]#从子进程中读取结果并返回whilenotqueue.empty():result.append(queue.get())返回结果ow=lambda:time.time()if__name__=='__main__':start=now()spider=BaiJiaHao()spider.run()print('done','TIME:',now()-start)运行结果: