• python异步(线程池,协程)概述


    多线程和多进程:
    优点:可以为阻塞操作提供异步执行
    缺点:无法无限制的创建线程

    进程池和线程池:
    好处:可以系统对进程和线程的创建和销毁的频率,从而降低系统的开销
    缺点:线程池和进程池是固定的。有上限。

    线程池的基本使用
    # 导入进程池的pool
    from multiprocessing.dummy import Pool
    # 实例化线程对象
    pool = Pool(4)
    #  map func iterator  chunksize
    pool.map(get_page,name_list)




    协程:
    单线程+异步协程(推介)
    evelent_loop: 事件循环,相当于一个无限循环,可以把一些函数注册到这个循环中

    coroutine:协程对象,我们可以把协程对象注册到事件循环中

    task:任务,他是对协程对象的进一步封装,包含了任务的每个状态

    future;代表将来执行或还没有执行的任务,task和future没有本质区别

    async: 定义一个协程
    await:永安里挂起阻塞方法的执行

    import asyncio
    #  提供了async await 两个关键字
    
    async def requests1(url):
        print('正在请求的url',url)
    
        print('请求成功',url)
    # async 修饰的函数,调用之后返回的是一个协程对象
    c = requests1('http://www.baidu.com')
    
    print(c)
    
    
    # 创建一个事件循环对象
    loop = asyncio.get_event_loop()
    
    # 将协程对象注册到loop中,然后启动loop  c 是协程对象
    
    loop.run_until_complete(c)
    
    
    
    
    
    # task 的使用
    
    loop = asyncio.get_event_loop()
    task = loop.create_task(c)  # 将协程对象 传入loop ,loop创建一个task对象
    
    print(task) # 打印任务对象,正在执行,协程状态
    
    # 将任务对象注册到loop
    
    loop.run_until_complete(task)
    print(task) # 打印任务对象,表示任务已经完成
    
    
    
    
    # future
    
    loop = asyncio.get_event_loop()
    
    # 创建future对象
    
    task = asyncio.ensure_future(c) # 任务对象
    print(task)
    loop.run_until_complete(task) # 注册
    
    print(task)
    绑定回调函数
     1 import asyncio
     2 #  提供了async await 两个关键字
     3 
     4 async def requests1(url):
     5     print('正在请求的url',url)
     6 
     7     print('请求成功',url)
     8     return  url
     9 # async 修饰的函数,调用之后返回的是一个协程对象
    10 c = requests1('http://www.baidu.com')
    11 
    12 print(c)
    13 
    14 
    15 
    16 # 绑定回调
    17 
    18 def callback_func(task):
    19     print(task.result()) # task.result() 返回任务对象的返回值
    20 
    21 loop = asyncio.get_event_loop()
    22 task = asyncio.ensure_future(c)
    23 # 当任务对象执行成功之后,执行回调函数 , 将回调函数绑定到任务对象
    24 task.add_done_callback(callback_func) # 默认将任务对象作为参数传递给回调函数
    25 loop.run_until_complete(task)

    多任务异步协程实现

    import asyncio
    import time
    
    async  def request(url):
        print('正在下载:',url)
        time.sleep(3)
        print("下载完成",url)
    
    
    urls = [
        'https://www.baidu.com',
        'https://www.sougou.com',
        'https://www.xinlang.com',
    ]
    start = time.time()
    # 任务列表,需要粗放多个任务对象
    tasks = []
    for url in urls:
        c = request(url) # 协程对象
        task = asyncio.ensure_future(c) # 任务对象
        tasks.append(task)
    
    loop = asyncio.get_event_loop() # 事件循环
    loop.run_until_complete(asyncio.wait(tasks)) # 注册
    
    print(time.time()-start) # 9秒, 没有节省时间
    
    原因出在哪里?
    time.sleep(3)
    在异步协程中,如果出现同步模块相关的代码,那么就无法实现异步。
    解决
    asyncio.sleep(3)
    
    当在asyncio中遇到阻塞操作必须进行手动挂起
    await
    
    
    
    import asyncio
    import time
    
    async  def request(url):
        print('正在下载:',url)
        # time.sleep(3)
        await  asyncio.sleep(3)
        print("下载完成",url)
    
    
    urls = [
        'https://www.baidu.com',
        'https://www.sougou.com',
        'https://www.xinlang.com',
    ]
    start = time.time()
    # 任务列表,需要粗放多个任务对象
    tasks = []
    for url in urls:
        c = request(url) # 协程对象
        task = asyncio.ensure_future(c) # 任务对象
        tasks.append(task)
    
    loop = asyncio.get_event_loop() # 事件循环
    loop.run_until_complete(asyncio.wait(tasks)) # 注册
    
    print(time.time()-start) # 3.003420114517212秒,

    aiohttp+多任务异步协程

    import asyncio
    import aiohttp
    import requests
    import time
    
    
    urls = [
        'https://www.baidu.com',
        'https://www.sougou.com',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
    ]
    
    async  def get_page(url):
        print("正在下载", url)
        res = requests.get(url)  # 基于同步代码 , 必须使用基于异步的网络请求模块
        print(res.status_code)
    
    
        print("下载外币",url)
    start = time.time()
    
    tasks = []
    
    for url in urls:
        c = get_page(url)
        task = asyncio.ensure_future(c)
        tasks.append(task)
    
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))
    
    print(time.time()-start) #2.431379795074463




    aiohttp:
    pip install aiohttp
    使用该模块的clientsesession

    import asyncio
    import aiohttp
    import requests
    import time
    
    
    urls = [
        'https://www.baidu.com',
        'https://www.sougou.com',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
        'https://www.bilibili.com/',
    ]
    
    async  def get_page(url):
        print("正在下载", url)
        # res = requests.get(url)  # 基于同步代码 , 必须使用基于异步的网络请求模块
        # print(res.status_code)
        async with  aiohttp.ClientSession() as session:
           async with  await session.get(url) as res :
               #         text() 返回字符串数据
               #         read() 返回二进制数据
               #         json() 返回json对象
               # 注意获取响应数据之前,一定要使用await手动挂起
                page_text = await  res.text(encoding='utf8')
    
                print(page_text)
    
        print("下载外币",url)
    start = time.time()
    
    tasks = []
    
    for url in urls:
        c = get_page(url)
        task = asyncio.ensure_future(c)
        tasks.append(task)
    
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))
    
    print(time.time()-start) # 1.3533799648284912
    
    #  RuntimeWarning: coroutine 'ClientResponse.text' was never awaited
    #   self._context.run(self._callback, *self._args)
    
    # 注意获取响应数据之前,一定要使用await手动挂起
    

      other

    aiohttp
    get ,post

    ua伪装
    get
    headers paramas

    post
    headers data , proxy 代理ip不是字典,而是字符串http://ip:port

    菜鸟的自白
  • 相关阅读:
    0Day – 2011.01.26
    JQuery_PHP 开始新的旅途
    0Day – 2011.01.25
    0Day – 2011.02.04
    Delphi 必须的一致.
    0Day – 2011.01.28
    0Day – 2011.02.23[From B4A]
    足球 看球悲惨的回忆.
    Delphi – EurekaLog6.1.01Ent下载地址
    ubuntu 拨号
  • 原文地址:https://www.cnblogs.com/lzjloveit/p/14162092.html
Copyright © 2020-2023  润新知