浅谈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数据处理实战(必看篇)
Jun 11 Python
python实现微信接口(itchat)详细介绍
Oct 23 Python
Bottle框架中的装饰器类和描述符应用详解
Oct 28 Python
python3.5 tkinter实现页面跳转
Jan 30 Python
python数字图像处理之骨架提取与分水岭算法
Apr 27 Python
解决Python requests库编码 socks5代理的问题
May 07 Python
pandas.dataframe按行索引表达式选取方法
Oct 30 Python
查看Python依赖包及其版本号信息的方法
Aug 13 Python
pytorch 实现cross entropy损失函数计算方式
Jan 02 Python
python文件操作seek()偏移量,读取指正到指定位置操作
Jul 05 Python
python利用os模块编写文件复制功能——copy()函数用法
Jul 13 Python
python判断字符串以什么结尾的实例方法
Sep 18 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实现无限极分类图文教程
2014/11/25 PHP
如何使Chrome控制台支持多行js模式——意外发现
2013/06/13 Javascript
jQuery中parent()方法用法实例
2015/01/07 Javascript
JS继承用法实例分析
2015/02/05 Javascript
jQuery选择器源码解读(二):select方法
2015/03/31 Javascript
基于ajax实现文件上传并显示进度条
2015/08/03 Javascript
JavaScript实现网页加载进度条代码超简单
2015/09/21 Javascript
分享网页检测摇一摇实例代码
2016/01/14 Javascript
WebSocket+node.js创建即时通信的Web聊天服务器
2016/08/08 Javascript
jQuery插件实现可输入和自动匹配的下拉框
2016/10/24 Javascript
jQuery实现动态显示select下拉列表数据的方法
2018/02/05 jQuery
关于Angularjs中跨域设置白名单问题
2018/04/17 Javascript
微信小程序日历插件代码实例
2019/12/04 Javascript
[38:23]完美世界DOTA2联赛循环赛 FTD vs PXG BO2第二场 11.01
2020/11/02 DOTA
Python中3种内建数据结构:列表、元组和字典
2014/11/30 Python
python获取本机外网ip的方法
2015/04/15 Python
Python与Java间Socket通信实例代码
2017/03/06 Python
Python中对象的引用与复制代码示例
2017/12/04 Python
python 搭建简单的http server,可直接post文件的实例
2019/01/03 Python
python redis 删除key脚本的实例
2019/02/19 Python
Python常见数据类型转换操作示例
2019/05/08 Python
python实现简易学生信息管理系统
2020/04/05 Python
Python3 利用face_recognition实现人脸识别的方法
2020/03/13 Python
Python中如何添加自定义模块
2020/06/09 Python
利用PyQt5+Matplotlib 绘制静态/动态图的实现代码
2020/07/13 Python
Html5 webRTC简单实现视频调用的示例代码
2020/09/23 HTML / CSS
AutoShack.com加拿大:北美主要的汽车零部件零售商
2019/07/24 全球购物
劲霸男装广告词改编版
2014/03/21 职场文书
优秀乡村医生事迹材料
2014/05/28 职场文书
机关保密承诺书
2014/06/03 职场文书
工作失误检讨书(经典集锦版)
2014/10/17 职场文书
2014年单位法制宣传日活动总结
2014/11/01 职场文书
介绍信怎么写
2015/01/30 职场文书
2016拓展训练心得体会范文
2016/01/12 职场文书
Python 阶乘详解
2021/10/05 Python
CentOS 7安装mysql5.7使用XtraBackUp备份工具命令详解
2022/04/12 MySQL