首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

我对Python多线程编程的通俗理解,希望帮助到你!

1 默认启动主线程

一般的,程序默认执行只在一个线程,这个线程称为主线程,例子演示如下:

导入线程相关的模块 :

threading的类方法 返回当前线程:

所以,验证了程序默认是在中执行。

获得这个线程的名字,其他常用方法,获得线程,判断线程是否存活等。

以上这些仅是介绍多线程的,因为到目前为止,我们有且仅有一个"干活"的主线程

2 创建线程

创建一个线程:

创建一个名称为的线程:

创建线程的目的是告诉它帮助我们做些什么,做些什么通过参数传入,参数类型为,函数就是可调用的:

线程已经全副武装,但是我们得按下发射按钮,启动start(),它才开始真正起飞。

打印结果如下,其中指定函数需要的参数i,类型为元祖。

至此,多线程相关的核心知识点,已经总结完毕。但是,仅仅知道这些,还不够!光纸上谈兵,当然远远不够。

接下来,聊聊应用多线程编程,最本质的一些东西。

3 交替获得CPU时间片

为了更好解释,假定计算机是单核的,尽管对于,这个假定有些多余。

开辟3个线程,装到中:

启动3个线程:

打印结果如下,,,三个线程,根据操作系统的调度算法,轮询获得CPU时间片,注意观察,线程可能被连续调度,从而获得时间片。

4 多线程抢夺同一个变量

多线程编程,存在抢夺同一个变量的问题。

比如下面例子,创建的10个线程同时竞争全局变量:

执行结果:

结果一切正常,每个线程执行一次,把的值加1,最后 变为10,一切正常。

运行上面代码十几遍,一切也都正常。

所以,我们能下结论:这段代码是线程安全的吗?

NO!

多线程中,只要存在同时读取和修改一个全局变量的情况,如果不采取其他措施,就一定不是线程安全的。

尽管,有时,某些情况的资源竞争,暴露出问题的概率:

本例中,如果线程0 在修改a后,其他某些线程还是get到的是没有修改前的值,就会暴露问题。

但是在本例中,这种修改操作,花费的时间太短了,短到我们无法想象。所以,线程间轮询执行时,都能get到最新的a值。所以,暴露问题的概率就变得微乎其微。

5 代码稍作改动,叫问题暴露出来

只要弄明白问题暴露的原因,叫问题出现还是不困难的。

想象数据库的写入操作,一般需要耗费我们可以感知的时间。

为了模拟这个写入动作,简化期间,我们只需要延长修改变量的时间,问题很容易就会还原出来。

重新运行代码,只需一次,问题立马完全暴露,结果如下:

看到,10个线程全部运行后,的值只相当于一个线程执行的结果。

下面分析,为什么会出现上面的结果:

这是一个很有说服力的例子,因为在修改a前,有0.2秒的休眠时间,某个线程延时后,CPU立即分配计算资源给其他线程。直到分配给所有线程后,根据结果反映出,0.2秒的休眠时长还没耗尽,这样每个线程get到的a值都是0,所以才出现上面的结果。

以上最核心的三行代码:

6 加上一把锁,避免以上情况出现

知道问题出现的原因后,要想修复问题,也没那么复杂。

通过python中提供的锁机制,某段代码只能单线程执行时,上锁,其他线程等待,直到释放锁后,其他线程再争锁,执行代码,释放锁,重复以上。

创建一把锁:

通过 获得锁,通过释放锁,它们之间的这些代码,只能单线程执行。

执行结果如下:

一起正常,其实这已经是单线程顺序执行了,就本例子而言,已经失去多线程的价值,并且还带来了因为线程创建开销,浪费时间的副作用。

程序中只有一把锁,通过 还能确保不发生死锁。但是,当程序中启用多把锁,还是很容易发生死锁。

注意使用场合,避免死锁,是我们在使用多线程开发时需要注意的一些问题。

7 总结

Python的多线程模型还有一些更深入的问题,在此不再展开,后续再讨论。

希望透过这篇文章,帮助你对多线程模型编程本质有些更清晰的认识。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200111A0OIK500?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券