zoukankan      html  css  js  c++  java
  • 学习笔记-Python基础18-asyncio异步、aiohttp、concurrent并发

    # asyncio
      - Python3.4开始引入标准库当中,内置对异步io的支持
      - asyncio本身是一个消息循环
      - 步骤:
        - 1、创建消息循环
        - 2、把协成加进去
        - 3、关闭

    # asyncio异步协成,简单案例1
    import threading
    import asyncio
    
    @asyncio.coroutine
    # 使用协成
    def hello():
        print('Hello world! (%s)' % threading.currentThread())
        print('Start...(%s)' % threading.currentThread())
        yield from asyncio.sleep(5)
        print('Done...(%s)' % threading.currentThread())
        print('Hello again! (%s)' % threading.currentThread())
    # 启动消息循环
    loop = asyncio.get_event_loop()
    # 定义任务
    tasks = [hello(), hello()]
    # asyncio使用wait等待tasks执行完毕
    loop.run_until_complete(asyncio.wait(tasks))
    # 关闭消息寻混
    loop.close()
    '''
    输出打印如下: Hello world! (<_MainThread(MainThread, started 9272)>) Start...(<_MainThread(MainThread, started 9272)>) Hello world! (<_MainThread(MainThread, started 9272)>) Start...(<_MainThread(MainThread, started 9272)>) Done...(<_MainThread(MainThread, started 9272)>) Hello again! (<_MainThread(MainThread, started 9272)>) Done...(<_MainThread(MainThread, started 9272)>) Hello again! (<_MainThread(MainThread, started 9272)>) ''' # asyncio异步用协成请求网络地址,案例2 import asyncio @asyncio.coroutine def wget(host): print('weget %s...' % host) # 异步请求网络地址 connect = asyncio.open_connection(host, 80) reader, writer = yield from connect header = 'GET / HTTP/1.0 Host: %s ' % host writer.writer(header.encode('utf-8')) yield from writer.drain() while True: line = yield from reader.readline() # http协议的换行使用 if line ==b' ': break print('%s header > %s' % (host, line.decode('utf-8').rstrip())) writer.close() loop = asyncio.get_event_loop() tasks = [wget(host) for host in ['www.sina.com.cn', 'www.sohu.com']] loop.run_until_complete(asyncio.wait(tasks)) loop.close() '''
    输出打印如下
    weget www.sina.com.cn... weget www.sohu.com... '''

    # asyncio and await
      - 为了更好的表示异步io
      - Python3.5引入
      - 让协成代码更简洁
      - 使用上,可以简单的进行替换
        - 用asyncio替换@asyncio.coroutine
        - 用await替换yield from

    import asyncio
    
    #@asyncio.coroutine
    # 使用协成
    async def hello():
        print('Hello world! (%s)' % threading.currentThread())
        print('Start...(%s)' % threading.currentThread())
        #yield from asyncio.sleep(5)
        await asyncio.sleep(5)
        print('Done...(%s)' % threading.currentThread())
        print('Hello again! (%s)' % threading.currentThread())
    # 启动消息循环
    loop = asyncio.get_event_loop()
    # 定义任务
    tasks = [hello(), hello()]
    # asyncio使用wait等待tasks执行完毕
    loop.run_until_complete(asyncio.wait(tasks))
    # 关闭消息寻混
    loop.close()

    # aiohttp
      - asyncio实现单线程的并发io,在客户端用处不大
      - 在服务器端可以asyncio+coroutine配合,因为http是io操作
      - asyncio实现了tcp,udp,ssl等协议
      - aiohttp是给与asyncio实现的http框架
      - pip install aiohttp安装

    # aiohttp案例
    import asyncio
    from aiohttp import web
    async def index(request):
        await asyncio.sleep(0.5)
        return web.Response(body=b'<h1>Index</h1>')
    async def hello(request):
        await asyncio.sleep(0.5)
        text = '<h1>hello,%s!</h1>' % request.match_info['name']
        return web.Response(body=text.encode('utf-8'))
    async def init(loop):
        app = web.Application(loop=loop)
        app.router.add_route('GET', '/', index)
        app.router.add_route('GET', '/hello/{name}', hello)
        srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8080)
        print('Server started at http://127.0.0.1:8080...')
        return srv
    loop = asyncio.get_event_loop()
    loop.run_until_complete(init(loop))
    loop.run_forever()

    # concurrent.futures
      - Python3新增的库
      - 类似其他语言的线程池概念
      - 利用multiprocessing实现真正的计算
      - 核心原理:以子进程的形式,并行运行多个python解释器
               从而令Python程序可以利用多核CPU来提升执行速度
               由于子进程与主解释器相分离,所以他们的全局解释器锁也是相互独立的
               每个子进程都能够完整的使用一个CPU内核
      - concurrent.futures.Executor
        - ThreadPoolExecutor
        - ProcessPoolExecutor
        执行的时候上面二者之间自行选择
      - submit(fn, args, kwargs)
        - fn:异步执行的函数
        - args, kwargs传参

    # 关于concurrent.futures案例
    from concurrent.futures import ThreadPoolExecutor
    import time
    
    def return_future(msg):
        time.sleep(3)
        return msg
    # 创建一个线程池
    pool = ThreadPoolExecutor(max_workers=2)
    # 往线程池加入两个task
    f1 = pool.submit(return_future, 'hello')
    f2 = pool.submit(return_future, 'world')
    # done等待执行完毕
    print(f1.done())
    time.sleep(3)
    print(f2.done())
    # result结果
    print(f1.result())
    print(f2.result())
    '''
    输出打印如下:
    False True hello world '''

    # concurrent中的map函数
      - map(fn, *iterables, timeout=None)
        - 第二个参数跟可迭代的对象
        - 很map函数类似
        - 函数需要异步执行
        - timeout:超时时间
        - map跟submit选一个使用就行

    # map案例
    import time, re
    import os, datetime
    from concurrent import futures
    
    data = ['1', '2']
    def wait_on(argument):
        print(argument)
        time.sleep(2)
        return "ok"
    ex = futures.ThreadPoolExecutor(max_workers=2)
    for i in ex.map(wait_on, data):
        print(i)
    '''
    输出打印如下:
    1
    2
    ok
    ok
    '''


    # Future
      - 小美的同学三分钟后要到小美家里做客,小美想送给同学一条烟作为礼物
      - 可是小美手头没烟
      - 于是让二狗帮忙去买烟,路程耗时20分钟
      - 等同学到家后,小美只好想辙指着空礼物盒对同学说这是给你的礼物,等你走的时候带走,先放这
      - 随后小美和同学吹了一小时牛逼
      - 期间27分钟后二狗带着烟回来了,把烟放入了礼物盒
      - 两小时候同学离开,并带走了小美送他的礼物
      - 礼物盒就是Future

  • 相关阅读:
    Div+CSS 布局
    Windows Mobile 参考:
    Linux export的作用
    CSS(2)基本语法
    HTML(6)超链接
    HTML(5)常用的格式标签
    HTML(8)表格
    CSS(1) CSS简介
    HTML(7)图像、背景和颜色
    HTML(10)框架
  • 原文地址:https://www.cnblogs.com/Cloudloong/p/9805315.html
Copyright © 2011-2022 走看看