• 异步回调 协程理论


    异步回调                                                                                                          回调:  其实说的是回调函数 ,给异步任务绑定一个函数,当任务完成时会自动调用该函数                                                 具体使用                                                                                                      当你往pool中添加 了一个异步任务,会返回一个表示结果的函数对象,有一个对象的绑定方法add_done_callback,需要一个函数作为参数,注意:回调函数必须有且 只有 一个参数 就是对象本身 通过对象.result()来获取结果     回调函数交给子线程来执行  谁有空谁处理

    优点:不用原地等待,任务结果可以立即获取到                            表达式:   

     from concurrent.futures import ThreadPoolExecutor

    import requests

    import threading

    #生产

    def  get_data(url):
      print('%s正在处理%s'%(threading.current_thread().name,url)
      resp = requests.get(url)
      print("%s获取完成”%url)
      return resp.text,url

    #消费
    def parser_data(f):
      res = f.result()
      print("解析长度为%s ,地址:%s"%(len(res[0],),res[1]))
      print("当前线程:%s"%threading.current_thread().name)

    urls = ["https://www.baidu.com/","https://www.bilibili.com/","https://sina.com/"]
    pool = ThreadPoolExecutor()
    for url in urls:
      f= pool.submit(get_data,url)#提交任务

      f.add_done_callback(parser_data)#绑定任务

    协程就是要用单线程实现并发

    为什么需要协程:                                                                                     GIL导致多个线程不能并行,效率低                                            CPYTHON中多个线程不能并行                                   一个线程如何能并发:                                                                         多道技术                  

                      切换+保存状态

        首先任务就是一堆代码 一堆代码就可以组成一个函数
        如何能使得可以在多个函数之间切换

    协程指的就是一个线程完成并发执行

    在CPYTHON中 如果你的任务是计算密集型,使用协程无法提高效率,反而在切换任务中导致效率降低,只能靠进程来解决问题

    IO密集型 多线程会比多进程效率高,应为线程的开销比进程小得多,本质上协程还是一个线程 所以一旦遇到IO操作 整个线程就卡主了

    协程仅在以下场景能够提高效率

       1 任务是Io密集型

       2 一定要可以检测到Io操作  并且在io即将阻塞时 切换到计算任务,从而使得cpu尽可能多的执行你的线程

    greenlet 无法检测io操作

    gevent 即可单线程实现并发 又可以检测io操作

    import  gevent 

    import gevent.monkey#打补丁必须放在 导入模块之前
    gevent.monkey.patch_all()

    import time

    import threading 

    def task1():
      print (a,b)

      print(task1)
      print(threading.current_thread())
      time.sleep(1)
      

        

    def task2():
    #for i in range(1000):
    print("task2")
    print(threading.current_thread())

    g1 = gevent.spawn(task1,123,321)
    g2 = gevent.spawn(task2)

     g1.join()
    g2.join()
  • 相关阅读:
    第一周软件测试
    第八周
    第七
    安卓第六周作业
    安卓第五周
    第四周作业
    Jsp第十次作业
    Jsp第九次作业(带验证码的email)
    Jsp第八次作业
    Jsp第七次作业email
  • 原文地址:https://www.cnblogs.com/tangda/p/10512758.html
Copyright © 2020-2023  润新知