【python】进阶--->并发编程之协程

本文介绍了协程的概念,对比了greenlet和gevent两种实现方式,强调了协程如何利用CPU上下文切换实现多任务并行,以及gevent的自动任务切换功能。最后展示了使用gevent进行网络请求并发处理的示例。
摘要由CSDN通过智能技术生成

一、协程

是另外一种实现多任务的方式,只不过比线程占用更小的执行单元(需要的资源).因为它自带cpu上下文,就可以在合适的时机,从一个协程切换到另一个协程.
(任务数量多于cpu时)系统在很短的时间内,将cpu轮流分配给不同的任务执行,造成了多任务同时运行的错觉.而每个任务在运行前,cpu需要知道任务从哪里开始加载,又从哪里开始运行.所以说,系统需要事先帮它设置好cpu寄存器和程序计数器.
cpu寄存器 : 是cpu内置的容量很小,但是速度极快的内存.
程序计数器 : 存储cpu正在执行的指令位置,即将执行的下一条指令的位置.
保存下来的上下文,会存储在系统中,并在任务重新调度执行再次加载进来,就能够保证任务还在原来的状态不受影响.

在这里插入图片描述

greenlet(pip install greenlet)
协程.switch(value)可以切换到指定的协程.

在这里插入图片描述

当创建一个greenlet的时候,首先会初始化一个空的栈,switch到这个栈时,会运行在greenlet构造时传入的函数(首先会打印12),如果在这个函数(test1)中switch到了另外的协程(到test2中打印56),那么这个协程会被挂起,等待再起通过switch切换回来执行.

gevent(pip install gevent)
greenlet已经实现了协程,但是需要人工切换,python还有个更强大的能够实现自动切换任务的模块:gevent.
gevent是一个并发框架,以协程greenlet为核心,其中有monkey类,将基于python线程直接转换成greenlet.
当一个协程遇到io操作(访问网络/睡眠等待),就会自动切换到其他的greenlet,等到io操作完成,再适当的时机切换回来继续执行.

在这里插入图片描述
在本文的最后呢,我附上了本节所学知识的全部代码,供大家参考,哪里有不对的地方随时在评论区指正哦~

# 协程的简单创建--->yield
import time
 
# def test1():
#     while True:
#         print('test1---')
#         yield
#         time.sleep(0.5)
#
#
# def test2():
#     while True:
#         print('test2---')
#         yield '返回值'
#         time.sleep(0.5)
 
 
# if __name__ == '__main__':
#     t1 = test1()
#     t2 = test2()
#     while True:
#         next(t1)
#         r = next(t2)
#         print(r)
 
 
# greenlet
# from greenlet import greenlet
# def test1():
#     print(12)
#     g2.switch()
#     print(34)
#     g2.switch()
#
# def test2():
#     print(56)
#     g1.switch()
#     print(78)
#
# g1 = greenlet(test1)
# g2 = greenlet(test2)
# g1.switch()
 
 
# gevent
# import gevent
# def test1():
#     for i in range(5):
#         print('test1---', i)
#         gevent.sleep(0)  # 阻塞,运行时能自动切换函数
#
# def test2():
#     for i in range(5):
#         print('test2---', i)
#         gevent.sleep(0)
#
#
# t1 = gevent.spawn(test1)
# t2 = gevent.spawn(test2)
# gevent.joinall([t1, t2])
 
 
# gevent
from gevent import monkey;monkey.patch_all()
import gevent
import requests
from datetime import datetime
 
 
def func(url):
    print('time:%s, get:%s' % (datetime.now(), url))
    re = requests.get(url)
    # print('time:%s, 从%s获取数据大小:%s' % (datetime.now(), url,
    #                                  len(re.text)))
    print(re.text)
 
func('https://www.baidu.com/')
 
# gevent.joinall([
#     gevent.spawn(func, 'https://www.baidu.com/'),
#     gevent.spawn(func, 'https://www.python.org/'),
#     gevent.spawn(func, 'https://www.github.com/'),
# ])

关于Python协程的介绍今天就到这里啦,后续我会为大家介绍网络编程的相关知识哦~
关注我,带你领略Python的风采~😍😍😍

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌上~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值