浅谈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中__call__方法示例分析
Oct 11 Python
python 读写、创建 文件的方法(必看)
Sep 12 Python
Python实现嵌套列表及字典并按某一元素去重复功能示例
Nov 30 Python
python flask中静态文件的管理方法
Mar 20 Python
利用Pandas 创建空的DataFrame方法
Apr 08 Python
pandas DataFrame数据转为list的方法
Apr 11 Python
Python利用openpyxl库遍历Sheet的实例
May 03 Python
这可能是最好玩的python GUI入门实例(推荐)
Jul 19 Python
python基于三阶贝塞尔曲线的数据平滑算法
Dec 27 Python
python词云库wordCloud使用方法详解(解决中文乱码)
Feb 17 Python
python使用pymongo与MongoDB基本交互操作示例
Apr 09 Python
Django视图类型总结
Feb 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
动态生成gif格式的图像要注意?
2006/10/09 PHP
解析link_mysql的php版
2013/06/30 PHP
php实例分享之html转为rtf格式
2014/06/02 PHP
CI框架整合widget(页面格局)的方法
2016/05/17 PHP
用HTML/JS/PHP方式实现页面延时跳转的简单实例
2016/07/18 PHP
PHP实现通过二维数组键值获取一维键名操作示例
2019/10/11 PHP
JS IE和FF兼容性问题汇总
2009/02/09 Javascript
jQuery Ajax之$.get()方法和$.post()方法
2009/10/12 Javascript
jQuery1.9.1针对checkbox的调整方法(prop)
2014/05/01 Javascript
javascript生成随机数的方法
2014/05/16 Javascript
JavaScript中的lastIndexOf()方法使用详解
2015/06/06 Javascript
javascript实现连续赋值
2015/08/10 Javascript
详解JavaScript的Date对象(制作简易钟表)
2020/04/07 Javascript
javascript 动态脚本添加的简单方法
2016/10/11 Javascript
jQuery.ajax实现根据不同的Content-Type做出不同的响应
2016/11/03 Javascript
bootstrap3使用bootstrap datetimepicker日期插件
2017/05/24 Javascript
微信小程序利用swiper+css实现购物车商品删除功能
2019/03/06 Javascript
如何利用Node.js与JSON搭建简单的动态服务器
2020/06/16 Javascript
vue监听dom大小改变案例
2020/07/29 Javascript
ES6中的Javascript解构的实现
2020/10/30 Javascript
Python中if __name__ == "__main__"详细解释
2014/10/21 Python
对python sklearn one-hot编码详解
2018/07/10 Python
Python OpenCV处理图像之滤镜和图像运算
2018/07/10 Python
Sanic框架路由用法实例分析
2018/07/16 Python
Python实现监控Nginx配置文件的不同并发送邮件报警功能示例
2019/02/26 Python
调用其他python脚本文件里面的类和方法过程解析
2019/11/15 Python
Python HTMLTestRunner库安装过程解析
2020/05/25 Python
使用keras实现非线性回归(两种加激活函数的方式)
2020/07/05 Python
Python 整行读取文本方法并去掉readlines换行\n操作
2020/09/03 Python
HTML5+CSS3实现机器猫
2016/10/17 HTML / CSS
法国美发器材和产品购物网站:Beauty Coiffure
2016/12/05 全球购物
Clarria化妆品官方网站:购买天然和有机化妆品系列
2018/04/08 全球购物
世界上最大的隐形眼镜商店:1-800 Contacts
2018/11/03 全球购物
写给妈妈的感谢信
2015/01/22 职场文书
事业单位工作人员岗前培训心得体会
2016/01/08 职场文书
python实现商品进销存管理系统
2022/05/30 Python