1.   前提

  之前我们学习了线程、进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位。按道理来说我们已经算是把cpu的利用率提高很多了。但是我们知道无论是创建多进程还是创建多线程来解决问题,都要消耗一定的时间来创建进程、创建线程、以及管理他们之间的切换。

  随着我们对于效率的追求不断提高,基于单线程来实现并发又成为一个新的课题,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发。这样就可以节省创建线进程所消耗的时间。

  为此我们需要先回顾下并发的本质:切换+保存状态

  cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长

   day34 协程

  ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态

   一:其中第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。

  为此我们可以基于yield来验证。yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下:


#1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级
#2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 

 

import time

def func1():

    for i in range(11):
        #yield
        print('这是我第%s次打印啦' % i)
        time.sleep(1)


def func2():
    g = func1()
    #next(g)
    for k in range(10):

        print('哈哈,我第%s次打印了' % k)
        time.sleep(1)
        #next(g)

#不写yield,下面两个任务是执行完func1里面所有的程序才会执行func2里面的程序,有了yield,我们实现了两个任务的切换+保存状态
func1()
func2()

通过yield实现任务切换+保存现场
通过yield任务切换+保存状态

相关文章:

  • 2022-01-02
  • 2021-04-06
  • 2021-06-25
  • 2021-05-04
  • 2022-02-12
  • 2021-10-27
  • 2021-12-25
  • 2022-02-28
猜你喜欢
  • 2021-11-13
  • 2022-12-23
  • 2022-12-23
  • 2022-03-06
  • 2021-10-29
  • 2022-12-23
  • 2021-10-16
相关资源
相似解决方案