一个故事讲完进程、线程和协程

作者:网友投稿 时间:2018-06-08 01:08

字号

很久以前,有两个程序,暂且称他们旺财和小强吧。

旺财和小强这两个程序都很长,每个都有十几万行。 他们两个的人生价值就是到CPU上去运行,把运行结果告诉人类。

一个故事讲完进程、线程和协程

CPU是稀缺资源,只有一个,他们俩必须排着队,轮流使用。

旺财从头到尾执行完了,让出CPU, 让小强从头儿去执行。

人类把这种处理方式叫做批处理。

一个故事讲完进程、线程和协程

进程

长久以来,两人相安无事。 后来CPU的速度越来越快, 远远超过了内存,硬盘的速度。

人类想到,这批处理系统的效率有点低啊,你看当小强需要从硬盘上读取数据的时候,CPU也一直在等待,这是多大的浪费啊!这时候完全可以让旺财来运行一下嘛!

当然得保存好小强的执行现场:具体执行到那一行程序指令了, 函数调用到什么层次了,每个函数调用都有什么样的参数,CPU寄存器中的值..... 等等一系列东西。

如果不把小强的执行现场给保存下来,等到小强的数据从银盘读完了,就没法回到中断处来继续执行了。

这个执行现场,再加上小强的代码,就是一个执行中的程序,被称为“进程” 。

旺财和小强在运行的时候,也被改造成了进程。

人类还规定:进程不能长时间占据CPU, 只能在CPU上执行一小会儿,然后马上切换到别的进程去执行。

旺财和小强不以为意:不就是执行一会儿,歇一会儿,然后继续执行嘛!

但是他们不知道的是,由于CPU运行速度超快,旺财和小强虽然在不断地切换运行,在人类那缓慢的世界里看来,旺财和小强好像是同时在执行一样。  这就是并发。

一个故事讲完进程、线程和协程

(在人类看来,小强和旺财似乎是在同时执行)

多年以后,他们俩才真正地实现了并行: 在一个豪华电脑中,每人都被分配了一个CPU , 真正地同时执行, 这是后话了。

线程

这时候旺财已经有了界面,还能访问网络,每当它联网的时候(这也是个非常非常耗时的操作),就得把CPU让给小强。

即使旺财再次被调度执行,由于网络数据还没有返回,他必须等待,什么事情都做不了,在人类看来,界面根本无法操作,旺财不响应了!  气得人类经常把旺财kill掉。

旺财心里苦,他很纳闷小强怎么就没有问题,小强不是要读写硬盘吗? 那也是很慢的操作啊。

小强说:“你傻啊,内部只有一个执行的流程,一遇到耗时的操作就得等待,你看看我,内部搞了两个执行流程(线程),一个用来读写硬盘(T1),另外一个处理界面(T2)。我和操作系统商量好了,如果T1在读写硬盘, 就可以调度我的T2来执行,这样界面至少还可以操作。 ”

一个故事讲完进程、线程和协程

旺财觉得很有意思,也采用了类似办法。

于是,一个进程中至少有一个执行的流程(主线程),也可以开启新的执行流程(线程)。

线程变成了最小的调度单位。

协程

这一天,旺财被一个叫做生产者和消费者的问题折腾地死去活来,两个线程,一个线程向队列中放数据,另外一个从队列中取数据,处理起两个线程的协作就显得很麻烦,不但需要加锁,还得做好线程的通知和等待。

正在感慨多线程编程之难的时候, 旺财震惊地发现,小强用了一个极为简单的办法把生产者,消费者问题给解决了。

这个方法的代码如下:

# 生产者 

def producer(c):    

    #其他代码   

    while True:           

        value = ...生成数据... 

        c.send(value) 

 

# 消费者 

def consumer():     

    #其他代码       

    while True

        value = yield  

        print(value) 

 

c = consumer() 

producer(c) 

“这....这怎么执行啊,那个yield是怎么回事?”  旺财表示不解。

“简单啊,你看那个生产者,是不是向消费者发送了数据? ” 小强说。

“对啊,然后呢,生产者发送了数据以后,会马上进行下一轮循环吗?”

“这就是关键所在了,”小强说,“ 它们是这么执行的:”

生产者发送数据,暂停运行,不进行下一轮循环

消费者其实一直在value = yield 那里等待,直到数据到来,现在数据来了,取出处理(value就是生产者发送过来的数据)。

消费者在循环中再次yield, 暂停执行。

生产者继续下一轮的循环,生成新的消息,发送给消费者。

一个故事讲完进程、线程和协程

责任编辑:CQITer新闻报料:400-888-8888   本站原创,未经授权不得转载
关键词 >>进程 线程 协程
继续阅读
热新闻
推荐
关于我们联系我们免责声明隐私政策 友情链接