首页 > 其他分享 >协程理论

协程理论

时间:2024-04-09 20:45:51浏览次数:29  
标签:协程 单线程 理论 线程 切换 time print

协程理论

一、单线程下的并发

  • 本节的主题是基于单线程来实现并发
    • 即只用一个主线程(很明显可利用的CPU只有一个)情况下实现并发
    • 为此我们需要先回顾下并发的本质:
      • 切换+保存状态
  • 当CPU正在运行一个任务会在两种情况下切走去执行其他的任务
    1. 该任务发生了阻塞
    2. 该任务计算的时间过长或有一个优先级更高的程序替代了它。

PS:第二种情况其实并不能提高效率,只是为了将优先级更高的任务先执行了罢了

​ 如果切换的几个任务都是纯计算类型的话,更会因为切换所增加的时间使得效率更低

[1]yield关键字

  • 基于yield来验证

    • yield本身就是一种在单线程下可以保存任务运行状态的方法
    • yield的使用方法:
    1 yield可以保存状态
    	yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级
    2 send可以把一个函数的结果传给另外一个函数
    	以此实现单线程内程序之间的切换
    

(1)串行执行

import time


def func1():
    for i in range(10000000):
        i + 1


def func2():
    for i in range(10000000):
        i + 1


start = time.time()
func1()
func2()
stop = time.time()
print(stop - start)

# 1.5161874294281006

(2)使用yeild实现并发

import time


def func1():
    while True:
        yield


def func2():
    g = func1()
    for i in range(10000000):
        i + 1
        next(g)


start = time.time()
func2()
stop = time.time()
print(stop - start)

# 1.8489949703216553
  • 频繁的切换会使效率更低
  • 对于单线程下,我们不可避免程序中出现IO操作,但如果我们能在自己的程序中(即用户程序级别,而非操作系统级别)控制单线程下的多个任务能在一个任务遇到IO阻塞时就切换到另外一个任务去计算,这样就保证了该线程能够最大限度地处于就绪态,即随时都可以被CPU执行的状态,相当于我们在用户程序级别将自己的IO操作最大限度地隐藏起来,从而可以迷惑操作系统,让其看到:该线程好像是一直在计算,IO比较少,从而更多的将CPU的执行权限分配给我们的线程。

二、协程介绍

[1]什么是协程

  • 是单线程下的并发,又称微线程,纤程

  • 一句话说明什么是线程:

    • 协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。
  • 需要强调的是:

    • python的线程属于内核级别的,即由操作系统控制调度(如单线程遇到io或执行时间过长就会被迫交出CPU执行权限,切换其他线程运行)
    • 单线程内开启协程,一旦遇到IO,就会从应用程序级别(而非操作系统)控制切换,以此来提升效率(!!!非IO操作的切换与效率无关)
  • 对比操作系统控制线程的切换,用户在单线程内控制协程的切换

[2]协程的优缺点

(1)优点

  • 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级
  • 单线程内就可以实现并发的效果,最大限度地利用cpu
  • 应用程序级别速度要远远高于操作系统的切换

(2)缺点

  • 协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程
  • 协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程(多个任务一旦有一个阻塞没有切,整个线程都阻塞在原地,该线程内的其他的任务都不能执行了)

[3]总结

  • 1.必须在只有一个单线程里实现并发
  • 2.修改共享数据不需加锁
  • 3.用户程序里自己保存多个控制流的上下文栈
  • 4.附加:一个协程遇到IO操作自动切换到其它协程(如何实现检测IO,yieldgreenlet都无法实现,就用到了gevent模块(select机制))

三、Greenlet

  • 安装
pip3 install greenlet
  • 使用
from greenlet import greenlet


def eat(name):
    print(f' {name} eat 1')
    g2.switch('hope')
    print(f' {name} eat 2')
    g2.switch()


def play(name):
    print(f' {name} play 1')
    g1.switch()
    print(f' {name} play 2')


g1 = greenlet(eat)
g2 = greenlet(play)

g1.switch('dream')

"""
 dream eat 1
 hope play 1
 dream eat 2
 hope play 2
"""

四、Gevent

  • Gevent 是一个第三方库
  • 可以轻松通过gevent实现并发同步或异步编程
  • gevent中用到的主要模式是Greenlet
  • 它是以C扩展模块形式接入Python的轻量级协程。
  • Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。

[1]安装

pip3 install gevent

[2]使用

import gevent


def func(*args, **kwargs):
    print(args)  # (1, 2, 3)
    print(kwargs)  # {'x': 4, 'y': 5}
    return 'ok'


def func2():
    ...
    
 	
g1 = gevent.spawn(func, 1, 2, 3, x=4, y=5)

g2 = gevent.spawn(func2)

g1.join()  # 等待g1结束

g2.join()  # 等待g2结束


# 拿到func1的返回值
result = g1.value

print(result)


"""
(1, 2, 3)
{'x': 4, 'y': 5}
ok
"""

标签:协程,单线程,理论,线程,切换,time,print
From: https://www.cnblogs.com/taoyuanshi/p/18124739

相关文章

  • 物流管理论文资料
    昆明斗南,汇聚了全国的鲜花交易,那么交易过后的物流是怎样的呢?1、所有交易过后的花卉都是由台车进行转运;2、转运后的物流方式分为三种,最早的模式全部靠空运发货,航班紧俏的时候经常发不走货;后期开始陆续有冷链陆运,陆运解决了空运运力的限制;现在大量的冷链物流网络覆盖全国了,反过来,空......
  • Python中协程(coroutine)详解
    一、协程和线程的比较及其适用场景1共用变量问题多线程中可能出现多个线程争抢变量,所以变量需要加锁;协程中任一时刻都只有一个线程,所以变量不需要加锁。但是协程虽然不像多线程争抢变量但仍是和多线程一样共用变量的,即共用变量在某处改变在另外一处引用时也会发生改变。2协......
  • 数据采集技术综合项目实战(协程式网络爬虫+数据预处理+数据可视化)附带详细步骤说明,干货
    数据采集部分:目标网址:https://item.jd.com/100066896338.html#none爬虫思路分析:1.确定采集目标:爬取“苹果15”的评论包括好评、差评、中评以及不同的评论对应的用户名、设备颜色、设备内存大小、版本号、评论发布时间等字段,共3000条以上的评论数目,如下图所示:2.查看评论来......
  • SAST-数据流分析方法-理论
    引言众所周知,数据流分析是实现污点分析的一种常用技术数据流分析分为过程内的数据流分析与过程间的数据流分析。前者是对一个方法体内的数据流分析,主要是基于CFG分析,不涉及方法调用;后者是基于不同方法间的数据流分析,主要是基于ICFG+CG分析,会涉及方法调用。一、过程内数据流分析......
  • 2024最新软件测试【测试理论+ Linux】面试题(内附答案)
    一、测试理论3.1你们原来项目的测试流程是怎么样的?我们的测试流程主要有三个阶段:需求了解分析、测试准备、测试执行。 1、需求了解分析阶段我们的SE会把需求文档给我们自己先去了解一到两天这样,之后我们会有一个需求澄清会议,我们会把不明白不理解的需求在会议上说出来,包......
  • 2024最新软件测试【测试理论+ 数据库】面试题(内附答案)
    一、测试理论3.1你们原来项目的测试流程是怎么样的?我们的测试流程主要有三个阶段:需求了解分析、测试准备、测试执行。 1、需求了解分析阶段我们的SE会把需求文档给我们自己先去了解一到两天这样,之后我们会有一个需求澄清会议,我们会把不明白不理解的需求在会议上说出来,包......
  • 软件测试理论(2)自动化测试
    自动化测试什么时候适用自动化测试?1)可重复的、不知疲倦地运动,对于数据能进行精确的大批量的比较的;2)回归测试3)在机械化的执行和比较测试执行的问题1)自动化测试没有有效的利用,使得手工测试太多。2)测试结果的捕获没有系统性,而且没有查看或调查3)缺陷报告必须......
  • 【MATLAB源码-第10期】基于matlab的pi/4DQPSK,π/4DQPSK的误码率BER理论和实际对比仿
    1、算法描述蓝牙是一种被广泛应用的无线通信标准,工作在2.4GHz-2.4835GHz频段范围,所用的调制方式有:GFSK,PI/4-DQPSK。北美第二代数字蜂窝移动通信系统D-AMPS和日本的JDC蜂窝系统均采用PI/4-DQPSK,欧洲的GSM系统采用GMSK。PI/4-DQPSK与GMSK等恒包络调制技术相比有更高的频谱利......
  • lambda演算入门 (软件工程与计算 理论部分2)20240406
    此文章来源于网络,是学习lambda演算过程的总结与复习,着重于探讨“为什么(Why)”与“怎么做(How)”,也希望能对看到它的人学习了解这个形式系统有些微帮助。由于之前看了不少wiki、tutorial、introduction之流,绝大多数读过之后仅知其然而不知其所以然,我不知道为什么它们都不解释为什......
  • 代码随想录算法训练营第二十四天 二十五 | 回溯的理论基础,77. 组合 216. 组合总和 II
    77.组合https://leetcode.cn/problems/combinations/description/List<List<Integer>>res=newArrayList<>();List<Integer>path=newArrayList<>();publicList<List<Integer>>combine(intn,intk){......