浅谈Python3多线程之间的执行顺序问题


Posted in Python onMay 02, 2020

一个多线程的题:定义三个线程ID分别为ABC,每个线程打印10遍自己的线程ID,按ABCABC……的顺序进行打印输出。

我的解法:

from threading import Thread, Lock


# 由_acquire解锁执行后释放_release锁
def _print(_id: str, _acquire: Lock, _release: Lock) -> None:
  for i in range(10):
    _acquire.acquire()
    print(f"id:{_id}")
    _release.release()


if __name__ == '__main__':
  # 创建三个锁供3个线程使用
  mutex1 = Lock()
  mutex2 = Lock()
  mutex3 = Lock()
  # 定义三个线程A、B、C
  # 线程A需要mutex1解锁执行后释放mutex2
  # 线程B需要mutex2解锁执行后释放mutex3
  # 线程C需要mutex3解锁执行后释放mutex1
  # 元组中第一位是自定义的线程ID,第二位是解锁需要的锁,第三位是释放的锁
  threads = [Thread(target=_print, args=[i[0], i[1], i[2]]) for i in
        [('A', mutex1, mutex2), ('B', mutex2, mutex3), ('C', mutex3, mutex1)]]
  # 把mutex2和mutex3这两把锁先用了以便阻塞线程2和线程3的执行
  mutex2.acquire()
  mutex3.acquire()
  # 接下来只有线程A可以先执行是因为mutex1并没有被占用
  # 线程B和线程C需要分别等待着锁2和锁3的释放才能继续执行
  [thr.start() for thr in threads]
  [thr.join() for thr in threads]

补充知识:python线程执行代码封装和执行顺序

线程-注意点

1. 线程执行代码的封装

通过上一小节,能够看出,通过使用threading模块能完成多任务的程序开发,为了让每个线程的封装性更完美,所以使用threading模块时,往往会定义一个新的子类class,只要继承threading.Thread就可以了,然后重写run方法

示例如下:

#coding=utf-8
import threading
import time

class MyThread(threading.Thread):
  def run(self):
    for i in range(3):
      time.sleep(1)
      msg = "I'm "+self.name+' @ '+str(i) #name属性中保存的是当前线程的名字
      print(msg)


if __name__ == '__main__':
  t = MyThread()
  t.start()

说明

python的threading.Thread类有一个run方法,用于定义线程的功能函数,可以在自己的线程类中覆盖该方法。而创建自己的线程实例后,通过Thread类的start方法,可以启动该线程,交给python虚拟机进行调度,当该线程获得执行的机会时,就会调用run方法执行线程。

2. 线程的执行顺序

#coding=utf-8
import threading
import time

class MyThread(threading.Thread):
  def run(self):
    for i in range(3):
      time.sleep(1)
      msg = "I'm "+self.name+' @ '+str(i)
      print(msg)
def test():
  for i in range(5):
    t = MyThread()
    t.start()
if __name__ == '__main__':
  test()

执行结果:(运行的结果可能不一样,但是大体是一致的)

I'm Thread-1 @ 0
  I'm Thread-2 @ 0
  I'm Thread-5 @ 0
  I'm Thread-3 @ 0
  I'm Thread-4 @ 0
  I'm Thread-3 @ 1
  I'm Thread-4 @ 1
  I'm Thread-5 @ 1
  I'm Thread-1 @ 1
  I'm Thread-2 @ 1
  I'm Thread-4 @ 2
  I'm Thread-5 @ 2
  I'm Thread-2 @ 2
  I'm Thread-1 @ 2
  I'm Thread-3 @ 2

说明

从代码和执行结果我们可以看出,多线程程序的执行顺序是不确定的。当执行到sleep语句时,线程将被阻塞(Blocked),到sleep结束后,线程进入就绪(Runnable)状态,等待调度。而线程调度将自行选择一个线程执行。上面的代码中只能保证每个线程都运行完整个run函数,但是线程的启动顺序、run函数中每次循环的执行顺序都不能确定。

3. 总结

每个线程默认有一个名字,尽管上面的例子中没有指定线程对象的name,但是python会自动为线程指定一个名字。

当线程的run()方法结束时该线程完成。

无法控制线程调度程序,但可以通过别的方式来影响线程调度的方式。

以上这篇浅谈Python3多线程之间的执行顺序问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python中的sort方法使用详解
Jul 25 Python
Python实现屏幕截图的代码及函数详解
Oct 01 Python
通过Python爬虫代理IP快速增加博客阅读量
Dec 14 Python
python中requests库session对象的妙用详解
Oct 30 Python
python、java等哪一门编程语言适合人工智能?
Nov 13 Python
Python3解决棋盘覆盖问题的方法示例
Dec 07 Python
python实现简易通讯录修改版
Mar 13 Python
实例讲解python中的协程
Oct 08 Python
python实现windows壁纸定期更换功能
Jan 21 Python
浅谈python3打包与拆包在函数的应用详解
May 02 Python
Python机器学习工具scikit-learn的使用笔记
Jan 28 Python
Pytorch 如何实现LSTM时间序列预测
May 17 Python
python继承threading.Thread实现有返回值的子类实例
May 02 #Python
Python3-异步进程回调函数(callback())介绍
May 02 #Python
浅谈Python中threading join和setDaemon用法及区别说明
May 02 #Python
判断Threading.start新线程是否执行完毕的实例
May 02 #Python
python中threading开启关闭线程操作
May 02 #Python
浅谈python3打包与拆包在函数的应用详解
May 02 #Python
构建高效的python requests长连接池详解
May 02 #Python
You might like
PHP4实际应用经验篇(3)
2006/10/09 PHP
php防注入及开发安全详细解析
2013/08/09 PHP
Drupal简体中文语言包安装教程
2014/09/27 PHP
laravel5实现微信第三方登录功能
2018/12/06 PHP
PHP架构及原理知识点详解
2019/12/22 PHP
JavaScript 解析Json字符串的性能比较分析代码
2009/12/16 Javascript
javascript的事件触发器介绍的实现
2014/06/05 Javascript
jQuery事件绑定和委托实例
2014/11/25 Javascript
Jquery实现图片预加载与延时加载的方法
2014/12/22 Javascript
JS实现点击文字对应DIV层不停闪动效果的方法
2015/03/02 Javascript
require.js的用法详解
2015/10/20 Javascript
基于Vue2的移动端开发环境搭建详解
2016/11/03 Javascript
微信小程序(三):网络请求
2017/01/13 Javascript
Vue计算属性的学习笔记
2017/03/22 Javascript
windows系统下更新nodejs版本的方案
2017/11/24 NodeJs
vue-cli 引入、配置axios的方法
2018/05/08 Javascript
React组件重构之嵌套+继承及高阶组件详解
2018/07/19 Javascript
使用ESLint禁止项目导入特定模块的方法步骤
2019/03/04 Javascript
详解async/await 异步应用的常用场景
2019/05/13 Javascript
vue 导航内容设置选中状态样式的例子
2019/11/01 Javascript
VUE页面中通过双击实现复制表格中内容的示例代码
2020/06/11 Javascript
[44:51]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第二场
2018/04/05 DOTA
Python二分查找详解
2015/09/13 Python
python实现通过flask和前端进行数据收发
2019/08/22 Python
python列表推导和生成器表达式知识点总结
2020/01/10 Python
tensorflow图像裁剪进行数据增强操作
2020/06/30 Python
解决PyCharm IDE环境下,执行unittest不生成测试报告的问题
2020/09/03 Python
CSS3实现超酷的黑猫警长首页
2016/04/26 HTML / CSS
HTML5 Canvas 实现K线图的示例代码
2019/12/23 HTML / CSS
一套VC试题
2015/01/23 面试题
体育教育专业毕业生自荐信
2013/11/15 职场文书
保荐人的岗位职责
2013/11/19 职场文书
交通事故调解协议书
2014/04/16 职场文书
小学红领巾广播稿(3篇)
2014/09/13 职场文书
2015年采购工作总结
2015/04/10 职场文书
教师廉政准则心得体会
2016/01/20 职场文书