【Python成长之路】来聊聊多线程的几位“辅助”

举报
技术火炬手 发表于 2020/07/28 09:40:46 2020/07/28
【摘要】 今天讲讲多线程的多位“辅助英雄”:锁、信号量、事件。

多线程示例

在介绍几位多线程方法前,我们先回归下多线程的使用。

image.png

image.png

在不使用各类方法时,多线程代码的结果为:运行时间为15S(5S为主函数等待时间,10S是子线程运行运行时间),即3个线程是同时运行的。另外,从结果中,可以看到多线程之间是随机运行的,可以说是相当混乱。

缺点:当前多个子线程存在相互抢占资源,会出现同一秒内同时打印hello的情况;另外子线程之间是乱序的,没有先来后到。

注:不知道为什么,微信公众号里设置代码功能不生效,因此只能截图了

锁示例

针对多线程里的锁方法,其实是将第一个子线程在运行时,将其他线程进行上锁,不让他们运行。有点像游乐场里,小朋友们在玩滑梯时,工作人员将他们一个个排队分好,在其中一个小朋友在玩时,其他小朋友不允许进入滑梯。

对应代码如下:

image.png

由于thread_demo方法代码是完全一样的,所以我就不再重复复制了。

加入锁后,运行结果为:运行时间为35S(5S为主函数等待时间,10*3 为3个子线程运行的总共时间),因为加入锁后,各子线程成了串行运行。

优点:加入锁后,子线程是依次运行,不再混乱;

缺点:整个程序运行时间将根据子线程数量成倍。

image.png

信号量示例

信号量的意思,是在一定线程数量内,允许他们乱序;当超出规定数量后,剩余的线程要进行等待。又比如游乐场里,碰碰车场地里允许10个小朋友同时进入,并由他们随机抢占自己想要的碰碰车;对超过10的小朋友只能等待第二场进入。

示例代码事下:

image.png

同样,针对信号量的使用方法,thread_demo方法代码也是一样的。

加入信号量后,运行结果是:总共运行时间是25S(因为信号量是2,即2个子线程是同时运行的,第3个子线程是等他们结束后才运行,所以5+10+10=25);并且信号量里的线程打印hello是乱序的。

优点:加入信号量后,可以适时调整并发线程数量,相当于锁和基础用法之间的中间态;

缺点:当信号量不足时,相当于锁的功能,后续子线程需要等待;当信号量过大时,相当于基础用法,即随机抢占资源。

image.png

事件示例

事件的引入,相当于在事件条件发生后才能允许子线程运行。怎么理解呢?比如游乐场里,小朋友们想去玩碰碰车,这时要家长同意。如果家长不同意,即使场地里空无一人,小朋友也不能进行玩。家长同意的动作,即多线程里的事件。

示例代码 如下:

image.png

image.png

从代码上看,除了hello函数需要做事件启动的判断外,thread_demo需要设置set();在未set()之间,子线程只能wait。

对应结果如下:总共运行时间为15S(5S为主函数等待时间,10S为子线程d的运行时间)。对于a/b/c三个子线程是waiting,当set后,进行hello打印。所以真正运行的只有线程d。

优点:根据不同事件,子线程可以实现不同的功能;相当于水龙头形状,即可以控制热水和冷水。

缺点:当事件发生后,子线程运行和基本用法是一样的,仍然是乱序的。就像家长们同意小朋友们进入游乐场后,小朋友们之间仍然是各自相互抢占。

image.png

好啦,锁、信号量、事件的简单使用方法已经介绍完了,希望对大家有所帮助!

作者:华为云特约供稿开发者  鹏哥贼优秀


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。