zoukankan      html  css  js  c++  java
  • 回调函数

    需要回调函数的场景:进程池中任何一个任务一旦处理完了,就立即告知主进程:我好了额,你可以处理我的结果了。主进程则调用一个函数去处理该结果,该函数即回调函数

    我们可以把耗时间(阻塞)的任务放到进程池中,然后指定回调函数(主进程负责执行),这样主进程在执行回调函数时就省去了I/O的过程,直接拿到的是任务的结果。

    from multiprocessing import Pool
    import requests
    import json
    import os
    
    def get_page(url):
        print('<进程%s> get %s' %(os.getpid(),url))
        respone=requests.get(url)
        if respone.status_code == 200:
            return {'url':url,'text':respone.text}
    
    def pasrse_page(res):
        print('<进程%s> parse %s' %(os.getpid(),res['url']))
        parse_res='url:<%s> size:[%s]
    ' %(res['url'],len(res['text']))
        with open('db.txt','a') as f:
            f.write(parse_res)
    
    
    if __name__ == '__main__':
        urls=[
            'https://www.baidu.com',
            'https://www.python.org',
            'https://www.openstack.org',
            'https://help.github.com/',
            'http://www.sina.com.cn/'
        ]
    
        p=Pool(3)
        res_l=[]
        for url in urls:
            res=p.apply_async(get_page,args=(url,),callback=pasrse_page)
            res_l.append(res)
    
        p.close()
        p.join()
        print([res.get() for res in res_l]) #拿到的是get_page的结果,其实完全没必要拿该结果,该结果已经传给回调函数处理了
    
    '''
    打印结果:
    <进程3388> get https://www.baidu.com
    <进程3389> get https://www.python.org
    <进程3390> get https://www.openstack.org
    <进程3388> get https://help.github.com/
    <进程3387> parse https://www.baidu.com
    <进程3389> get http://www.sina.com.cn/
    <进程3387> parse https://www.python.org
    <进程3387> parse https://help.github.com/
    <进程3387> parse http://www.sina.com.cn/
    <进程3387> parse https://www.openstack.org
    [{'url': 'https://www.baidu.com', 'text': '<!DOCTYPE html>
    ...',...}]
    '''
    爬虫案例
    from multiprocessing import Pool
    import time,random
    import requests
    import re
    
    def get_page(url,pattern):
        response=requests.get(url)
        if response.status_code == 200:
            return (response.text,pattern)
    
    def parse_page(info):
        page_content,pattern=info
        res=re.findall(pattern,page_content)
        for item in res:
            dic={
                'index':item[0],
                'title':item[1],
                'actor':item[2].strip()[3:],
                'time':item[3][5:],
                'score':item[4]+item[5]
    
            }
            print(dic)
    if __name__ == '__main__':
        pattern1=re.compile(r'<dd>.*?board-index.*?>(d+)<.*?title="(.*?)".*?star.*?>(.*?)<.*?releasetime.*?>(.*?)<.*?integer.*?>(.*?)<.*?fraction.*?>(.*?)<',re.S)
    
        url_dic={
            'http://maoyan.com/board/7':pattern1,
        }
    
        p=Pool()
        res_l=[]
        for url,pattern in url_dic.items():
            res=p.apply_async(get_page,args=(url,pattern),callback=parse_page)
            res_l.append(res)
    
        for i in res_l:
            i.get()
    
        # res=requests.get('http://maoyan.com/board/7')
        # print(re.findall(pattern,res.text))

    如果在主进程中等待进程池中所有任务都执行完毕后,再统一处理结果,则无需回调函数

    from multiprocessing import Pool
    import time,random,os
    
    def work(n):
        time.sleep(1)
        return n**2
    if __name__ == '__main__':
        p=Pool()
    
        res_l=[]
        for i in range(10):
            res=p.apply_async(work,args=(i,))
            res_l.append(res)
    
        p.close()
        p.join() #等待进程池中所有进程执行完毕
    
        nums=[]
        for res in res_l:
            nums.append(res.get()) #拿到所有结果
        print(nums) #主进程拿到所有的处理结果,可以在主进程中进行统一进行处理

    进程池的其他实现方式:https://docs.python.org/dev/library/concurrent.futures.html

  • 相关阅读:
    沙尘天气,但还是要坚持锻炼
    为了欧冠,堕落两天
    NRF24L01测试板子完成了
    昨天参加ti的研讨会了
    自我安慰一下
    功率W与dBm的对照表及关系
    短时间提高英语口语方法
    看了一个星期的欧洲杯,熬阿
    最近比较忙,项目较累
    后台获取js赋给服务器控件的值
  • 原文地址:https://www.cnblogs.com/wanghaohao/p/7444827.html
Copyright © 2011-2022 走看看