python之协程

本文介绍了多进程、多线程及协程的概念与应用场景,并详细探讨了协程的多种实现方式,包括手动切换、自动切换及基于Python生成器的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、对比多进程、多线程和协程

相同点:都是为了多任务的并发执行

多进程:应用于中大型项目开发过程中,对于数据管理更加严格的项目并发操作
通过进程管理数据,通过线程运行任务,完成并发处理数据。

多线程:微进程,应用于多任务处理机制,对于数据的操作并不是管理严格
如:如果出现了一个大文件的复制粘贴功能-> 多线程 效率非常高
如果出现了一个单路大数据量的的运算功能-> 多线程 < 单线程

Django web framework
    多人同时访问网站-> 网站并发量-> 多线程的方式实现
        每个线程,会服务一个访问数据请求

协程:微线程,应用于多任务处理机制,对于数据的处理更加的松散!
协程的方式,对于注重多任务处理机制的软件,更加的友好!性能处理更加优秀!

Tornado web framework
    多人同时访问网站-> 网站并发量-> 事件轮询机制[epoll/Kqueue系统内核]
        单线程多任务事件轮询机制_>并发处理效率,> Django

2、协程的由来

2.1模拟单线程多任务
# #单线程多任务
import time
# 1模拟单线程多任务
# 实质是一个线程中串行运行两个任务

def sing():
    print("我把歌唱给你听...")

def dance():
    print("不如跳舞...")

if __name__ == '__main__':

    while True:
        sing()
        dance()
        time.sleep(1)

# 模拟:了解单线程多任务
# 实质:两个函数互相调用,会急剧消耗cpu,因为后一个函数没执行完时,前一个函数也不会释放内存
def sing():
    print("我把歌唱给你听...")
    time.sleep(0.5)
    dance()

def dance():
    print("不如跳舞...")
    time.sleep(0.5)
    sing()

if __name__ == '__main__':
    sing()

函数相互调用的弊端:
这里写图片描述


为解决单线程多任务的执行,引进了协程,两个任务在一个线程中,轮换执行任务

这里有三种中任务切换的方式:
这里写图片描述

2.2、协程序——手动切换
#安装gevent模块,该模块提供了基于事件的单线程多任务事件管理机制
from greenlet import greenlet

def sing():
    while True:
        print("唱歌...")
        g2.switch()

def dance():
    while True:
        print("跳舞...")
        g1.switch()

if __name__ == '__main__':
    #单任务多任务操作

    #创建两个协程
    g1 = greenlet(sing)
    g2 = greenlet(dance)

    # 首选切换让g1执行
    g1.switch()
2.3、协程序——自动切换
#2、基于事件的协程让步执行方式:自动切换
import gevent

def sing():
    while True:
        print("唱歌...")
        gevent.sleep(1)

def dance():
    while True:
        print("跳舞...")
        gevent.sleep(2)


if __name__ == '__main__':
    #创建协程序
    g1 = gevent.spawn(sing)
    g2 = gevent.spawn(dance)

    #独占运行
    g1.jion()
    g2.jion()

3、基于python生成器的协程操作

关键字yield
生成器:当代码执行到这行时,预加载准备,但是函数不会执行
而是预加载代码需要运行时,才执行

def sing():
    while True:
        print("唱歌")
        yield()# 协程让步->让同一个线程中的其他协程可以执行。

def dance():
    while True:
        print("跳舞")
        next(s)

if __name__ == '__main__':
    s = sing()
    d = dance()

4.1python3.4提供了异步IO模块:asyncio[异步非阻塞]

#python3.4提供了异步IO模块:asyncio[异步非阻塞]
#协程:coroutine
import asyncio

#声明一个协程函数
@asyncio.coroutine
def sing():
    while 1:
        print("我把歌声唱给你听")
        #协程让步:执行异步操作,让另一个函数也同时执行
        yield from asyncio.sleep(1)

@asyncio.coroutine
def dance():
    while True:
        print("不如跳舞...")
        yield from asyncio.sleep(2)

if __name__ == '__main__':
    #创建一个事件轮询对象
    loop = asyncio.get_event_loop()

    #编译多个函数[事件]到轮询对象中
    loop.run_until_complete(asyncio.gather(sing(),dance()))

    #关闭事件轮询对象
    loop.close()

轮询对象中的函数会循环执行
这里写图片描述

4.2、python3.5 对于异步IO的协程操作方式有有了新的改进

#python3.5 对于异步IO的协程操作方式有有了新的改进
#可以直接定义异步处理函数,通过异步处理函数完成协程并发操作
import asyncio

async def sing():
    #声明异步函数
    while True:
        print("唱吧唱吧。。。")
        await asyncio.sleep(1)#模拟这里产生了一个异步操作{异步IO}

async def dance():
    #声明异步函数
    while True:
        # time.sleep(2)
        print("不如跳舞")
        await asyncio.sleep(2)

if __name__ == '__main__':
    #创建一个事件轮询对象
    loop = asyncio.get_event_loop()

    # 加载多个函数【任务】到轮询对象中
    loop.run_until_complete(asyncio.gather(sing(),dance()))

    loop.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值