IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> python网络编程三--异步编程之协程 -> 正文阅读

[Python知识库]python网络编程三--异步编程之协程

异步编程之协程(asyncio模块)

协程:协程是在用户空间,基于生成器(yield),在单线程内(而非多线程的操作系统调度),实现的一种非抢占式调度;当一个协程主动让出控制权,另一个协程才会被调度。。python3.4引入。

协程在单线程内完成,没有多线程切换带来的开销
单线程内调度,不需要锁机制
多CPU下,多进程+协程,实现进程并发,同时发挥协程在单进程的优势

1 asyncio模块

通过asyncio模块实现协程,asyncio模块其实是一个框架,包括异步IO,事件循环、协程、任务等内容。

1、问题引入: 以下示例,在单线程内,通过生成器(yield语句)完成任务调度,让两个函数交替执行,看似并行。这种调度是在用户空间由用户设计的,而不是通过多线程或多进程由操作系统调度。协程就是基于yield实现的。

def foo1():
    for i in range(3):
        print("foo1:{}".format(i))
        yield


def foo2():
    for i in range(3):
        print("foo1:{}".format(i))
        yield

a = foo1()
b = foo2()
for i in range(3):
    next(a)
    next(b)

2、事件循环: 事件循环是asyncio提供的核心运行机制
理解示例:

import asyncio
from tool.show_thread import show_thread


#  一个生成器函数,在上门加一个协程装饰器,它就变成了一个协程函数。
@asyncio.coroutine  # python3.4版本使用协程装饰器 + yield。
def sleep(x):
    for i in range(3):
        print("sleep {}".format(i))
        yield from asyncio.sleep(x)


async def new_sleep(x):  # python3.5开始,语言通过`async def`关键字原生支持定义协程函数。通过`async def`关键字定义的协程函数,可以使用`asyncio.iscoroutinefunction()`判断是不是协程函数;使用`asyncio.iscoroutine`判断是不是协程对象。
    for i in range(3):
        print("new sleep:{}".format(i))
        await asyncio.sleep(x)  # 使用`async def`,则函数内就不能用yield了,yield语句用await来替换,也就是说这种语法有它自己的关键字了,虽然原理都一样。


if __name__ == '__main__':
    show_thread()
    # 事件循环是asyncio提供的核心运行机制
    loop = asyncio.get_event_loop()  # 获取一个事件循环对象对象
    print("is coroutine function:{}.".format(asyncio.iscoroutinefunction(new_sleep)))
    task = [sleep(3), new_sleep(3)]
    # loop.run_until_complete(sleep(3))  # 运行至指定的future对象运行完成
    # loop.is_running()  # 事件是否在运行
    # loop.stop()  # 停止事件
    loop.run_until_complete(asyncio.wait(task))  # asyncio.wait(task),task是一个协程函数对象列表。把所有任务丢进列表中,就实现交替运行
    loop.close()  # 关闭事件循环对象

2 使用协程实现群聊

import asyncio


async def my_handle(client_reader, client_writer):
    while True:
        data = await client_reader.read(1024)
        print("client reader:{}".format(dir(client_reader)))
        print("client writer:{}".format(dir(client_writer)))
        client = client_writer.get_extra_info("peername")
        msg = "{} your message {}".format(client, data.decode()).encode()
        client_writer.write(msg)
        await client_writer.drain()


def my_chat(*args):
    ip = "127.0.0.1"
    port = 9998
    loop = asyncio.get_event_loop()
    chat = asyncio.start_server(my_handle, ip, port, loop=loop)
    server = loop.run_until_complete(chat)
    print("current socket:{}".format(server))
    try:
        loop.run_forever()
    except Exception as e:
        print(e)
        pass
    finally:
        server.close()
        loop.close()


if __name__ == '__main__':
    my_chat()

3 aiohttp模块

使用aiohttp模块实现http server和http client示例:

import asyncio
from aiohttp import web
from aiohttp import ClientSession


class MyServer:

    @classmethod
    async def get_html_index_handle(cls, req: web.Request):
        return web.Response(text=req.path, status=201)

    @classmethod
    async def get_html_handle(cls, req: web.Request):
        print(req.match_info)
        print(req.query_string)  # http://127.0.0.1:9998/1?name=12301
        return web.Response(text=req.match_info.get("id", "0000"), status=200)

    def implement_server(self):
        app = web.Application()
        app.router.add_get("/", self.get_html_index_handle)  # http://127.0.0.1:9998/
        app.router.add_get("/{id}", self.get_html_handle)  # http://127.0.0.1:9998/12301

        web.run_app(app, host="127.0.0.1", port=9998)


class MyClient:

    @classmethod
    async def get_html(cls, url: str):
        async with ClientSession() as session:
            async with session.get(url) as res:
                print(res.status)
                print(await res.text())

    def implement_client(self):
        url = "http://127.0.0.1:9998/ziroom-web"

        loop = asyncio.get_event_loop()
        loop.run_until_complete(self.get_html(url))
        loop.close()
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:00:11  更:2022-08-19 19:02:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/22 0:34:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码