zoukankan      html  css  js  c++  java
  • 协程

    协程目的:

    1单线程下实现并发:协程

    解决方案:一个任务运行的过程中把它打断(保存此时的状态)切换到另一个任务中,运行一段时间再切换回来,反复来回切换

    注:并发指的是多个任务看起来是同时运行的

      并发实现的本质:切换+保存状态

      并发、并行、串行:

      并发:看起来是同时运行,切换+保存状态

      并行:真正意义上的同时运行,只有在多cpu情况下才实现并行,4个cpu能够并行4个任务

      串行:一个任务完完整整地执行完毕才运行下一个任务

    例如以下程序中生产者和消费者数据的来回切换:(应用程序自己控制切换及保存状态,速度更快)

    import time
    def consumer():
        '''任务1:接收数据,处理数据'''
        while True:
            x=yield
    
    
    def producer():
        '''任务2:生产数据'''
        g=consumer()
        next(g)
        for i in range(10000000):
            g.send(i)
    
    start=time.time()
    #基于yield保存状态,实现两个任务直接来回切换,即并发的效果
    #PS:如果每个任务中都加上打印,那么明显地看到两个任务的打印是你一次我一次,即并发执行的.
    producer() #1.0202116966247559
    
    stop=time.time()
    print(stop-start)
    View Code

    但如果一个程序中是纯计算活的话,来回切换意义不大,如下:

    # 纯计算的任务串行执行
    import time
    def task1():
        res=1
        for i in range(1000000):
            res+=i
    
    def task2():
        res=1
        for i in range(1000000):
            res*=i
    
    start=time.time()
    task1()
    task2()
    stop=time.time()
    print(stop-start)
    
    
    # 纯计算的任务并发执行
    import time
    def task1():
        res=1
        for i in range(1000000):
            res+=i
            yield    #切换到task2
    
    def task2():
        g=task1()
        res=1
        for i in range(1000000):
            res*=i
            next(g)   #切换到task1
    
    start=time.time()
    #基于yield保存状态,实现两个任务直接来回切换,即并发的效果
    #PS:如果每个任务中都加上打印,那么明显地看到两个任务的打印是你一次我一次,即并发执行的.
    task2()
    stop=time.time()
    print(stop-start)

    打印结果:

    0.22888588905334473
    0.42775511741638184

    可以看出做纯计算任务并发执行的时间是串行执行的2倍,速度慢了

    所以单线程下实现并发是为了提高效率,检测多个任务的IO行为,遇到IO再切到自己单线程下的另外一个任务去执行,这样就把单线程下的IO问题给尽可能多的缩减下来(相当于‘欺骗了’操作系统,在操作系统看来你一直处于工作状态,操作系统才不会把cpu拿走),这样单线程就尽可能多的处于计算过程,也就是处于就绪态。

    强调:

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

    协程优点:

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

    缺点:

    #1. 协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程
    #2. 协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程
  • 相关阅读:
    HTML+CSS笔记 CSS进阶续集
    HTML+CSS笔记 CSS进阶
    HTML+CSS笔记 CSS入门续集
    HTML+CSS笔记 CSS入门
    test
    Python Paramiko模块安装和使用
    RedHat升级Python到2.7.6
    python数据库操作常用功能使用详解(创建表/插入数据/获取数据)
    5、使用EF对后台SysSample数据增删改查
    4、创建SQL数据库,添加EF实体数据模型
  • 原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/11779561.html
Copyright © 2011-2022 走看看