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

发布时间:2023年12月20日

一、协程

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

文章来源:https://blog.csdn.net/m0_75141643/article/details/135069704
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。