是另外一种实现多任务的方式,只不过比线程占用更小的执行单元(需要的资源).因为它自带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的风采~😍😍😍