浅析线程的信号量和进程的信号量用法

描述

信号量-Semaphore

线程的信号量和进程的信号量用法无异:

线程
线程

事件-Event

通过event类将两个方法连接起来进行沟通:

线程线程

线程池-ThreadPoolExecutor

线程池和进程池用法是几乎无异的,但是要注意它导入的模块,提交的方法,参数的填写方法,以及关闭的方法:

线程线程

如果涉及返回值的时候呢?

直接打印的话会打印出一串内存地址(自己尝试)这时候需要调用.result方法(第14行)

线程线程

但是我们从结果上看,程序变成了一个同步程序,大大降低了我们的效率。这时候我们可以采用新建列表的方式来进行优化:

线程线程

协程-greenlet

我们都知道:

①进程是计算机中最小的资源分配单位·

②线程是计算机中能被cpu调度的最小单位

现在有一个问题:能开启的线程和进程是有限的,但是我们要处理的任务是无限的。比如我现在有5万个任务要执行,难道我去开5万个线程吗?然后假设我开了300个线程,但是这300个线程都阻塞了,我仍然没有充分利用CPU,(理想的情况是开启一个线程,没有IO只有计算,这叫充分利用CPU,但大多数的情况不是这样的,多多少少会有一些阻塞情况),这时候协程(纤程)就派上用场了。一条线程在多个任务之间来回切换,切换这个动作是需要浪费时间的,但是对于CPU、操作系统来说,协程是不存在的,它们只能看见最小单位即线程。把一个线程的工作分成了好几个任务,在多个任务中来回切换的现象称为协程。

线程

写一个简单地生产者消费者模型:

线程

①协程能把一个线程的执行明确的区分开

②两个任务,协程帮助我记住哪个任务执行到哪个位置上了,并且实现安全的切换

③一个任务不得不陷入阻塞了,在这个任务阻塞的过程中切换到另一个任务继续执行

④你的程序只要还有任务需要执行你的当前线程永远不会阻塞

⑤利用协程在多个任务陷入阻塞的时候进行切换,来保证一个线程在处理多个任务的时候总是在忙碌

⑥能够更加充分的利用cpu,抢占更多的时间片

⑦无论是进程还是线程都是由操作系统来切换的,开启过多的线程、进程会给操作系统的调度增加负担

⑧如果我们是使用的协程,协程在程序之间的切换操作系统感知不到

⑨无论开启多少个协程对操作系统来说总是一个线程在执行,操作系统的调度不会有任务的压力

⑩协程的本质就是一条线程,所以完全不会产生数据安全的问题。

对于协程所需要用到的模块主要有两个,greenlet和gevent,其中greenlet是gevent的底层逻辑模块,主要控制协程的切换(手动),gevent可以当做是greenlet的升级版,功能比greenlet更加全面,需要安装,安装后即可直接使用。

线程

线程

可以看出,greenlet.switch可以帮助程序员手动切换阻塞,但是如果想要自动切换还需要用到gevent。

协程-gevent

gevent就是greenlet的完善版:

线程

线程

但是我们如果把gevent.sleep换成time.sleep呢?

线程

线程

很明显,阻塞没有被识别到,所以我们需要用到导入monkey,这样就能将一些常见的阻塞识别。

线程

线程




审核编辑:刘清




 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分