浅谈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实现一次创建多级目录的方法
May 15 Python
Python写的一个简单监控系统
Jun 19 Python
Python+matplotlib实现填充螺旋实例
Jan 15 Python
TensorFlow saver指定变量的存取
Mar 10 Python
使用pandas模块读取csv文件和excel表格,并用matplotlib画图的方法
Jun 22 Python
获取Pytorch中间某一层权重或者特征的例子
Aug 17 Python
Window10下python3.7 安装与卸载教程图解
Sep 30 Python
如何基于python操作excel并获取内容
Dec 24 Python
Python面向对象之私有属性和私有方法应用案例分析
Dec 31 Python
Django 设置admin后台表和App(应用)为中文名的操作方法
May 10 Python
python反编译教程之2048小游戏实例
Mar 03 Python
Python数据类型最全知识总结
May 31 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
php微信支付之公众号支付功能
2018/05/30 PHP
PHP中检查isset()和!empty()函数的必要性
2019/02/13 PHP
使用Javascript和DOM Interfaces来处理HTML
2006/10/09 Javascript
Document对象内容集合(比较全)
2010/09/06 Javascript
javascript天然的迭代器
2010/10/29 Javascript
浅谈JavaScript函数参数的可修改性问题
2013/12/05 Javascript
jquery 获取dom固定元素 添加样式的简单实例
2014/02/04 Javascript
js和jquery中循环的退出和继续学习记录
2014/09/06 Javascript
jQuery获取DOM节点实例分析(2种方式)
2015/12/15 Javascript
AngularJS 使用 UI Router 实现表单向导
2016/01/29 Javascript
AngularJS指令与指令之间的交互功能示例
2016/12/14 Javascript
关于JS与jQuery中的文档加载问题
2017/08/22 jQuery
vue+webpack 打包文件 404 页面空白的解决方法
2018/02/28 Javascript
Vue中"This dependency was not found"问题的解决方法
2018/06/19 Javascript
JS实现的冒泡排序,快速排序,插入排序算法示例
2019/03/02 Javascript
使用webpack搭建pixi.js开发环境
2020/02/12 Javascript
vue组件暴露和.js文件暴露接口操作
2020/08/11 Javascript
使用优化器来提升Python程序的执行效率的教程
2015/04/02 Python
Python实现快速排序和插入排序算法及自定义排序的示例
2016/02/16 Python
详解python 拆包可迭代数据如tuple, list
2017/12/29 Python
Python3.4学习笔记之 idle 清屏扩展插件用法分析
2019/03/01 Python
django2.2安装错误最全的解决方案(小结)
2019/09/24 Python
Python一行代码解决矩阵旋转的问题
2019/11/30 Python
css3 图片圆形显示 如何CSS将正方形图片显示为圆形图片布局
2014/10/10 HTML / CSS
德国网上宠物店:Zoobio
2018/05/23 全球购物
卡骆驰新加坡官网:Crocs新加坡
2018/06/12 全球购物
.net面试题
2015/12/22 面试题
质检的岗位职责
2013/11/17 职场文书
文明礼仪小标兵事迹
2014/01/12 职场文书
《乞巧》教学反思
2014/02/27 职场文书
初中学校军训方案
2014/05/09 职场文书
2014组织生活会方案
2014/05/19 职场文书
会计岗位说明书
2014/07/29 职场文书
2014年教师节讲话稿5篇
2014/09/10 职场文书
学生偷窃检讨书
2014/09/25 职场文书
教师节获奖感言
2015/07/31 职场文书