浅谈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进阶教程之文本文件的读取和写入
Aug 29 Python
Python实现获取照片拍摄日期并重命名的方法
Sep 30 Python
python如何发布自已pip项目的方法步骤
Oct 09 Python
Python爬虫之正则表达式的使用教程详解
Oct 25 Python
Python终端输出彩色字符方法详解
Feb 11 Python
python 解压、复制、删除 文件的实例代码
Feb 26 Python
Python PyQt5整理介绍
Apr 01 Python
Python 通过监听端口实现唯一脚本运行方式
May 05 Python
在keras中model.fit_generator()和model.fit()的区别说明
Jun 17 Python
Matlab中plot基本用法的具体使用
Jul 17 Python
使用tensorflow进行音乐类型的分类
Aug 14 Python
利用Python如何制作贪吃蛇及AI版贪吃蛇详解
Aug 24 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
增加反向链接的101个方法 站长推荐
2007/01/31 PHP
php网页后退不再出现过期
2007/03/08 PHP
php 删除一个数组中的某个值.兼容多维数组!
2012/02/18 PHP
Zend Framework入门知识点小结
2016/03/19 PHP
THINKPHP3.2使用soap连接webservice的解决方法
2017/12/13 PHP
Laravel如何创建服务器提供者实例代码
2019/04/15 PHP
ThinkPHP类似AOP思想的参数验证的实现方法
2019/12/18 PHP
JQuery读取XML文件数据并显示的实现代码
2009/12/16 Javascript
Javascript 面向对象(一)(共有方法,私有方法,特权方法)
2012/05/23 Javascript
javascript中style.left和offsetLeft的用法说明
2014/03/07 Javascript
在JavaScript中重写jQuery对象的方法实例教程
2014/08/25 Javascript
深入理解JavaScript系列(41):设计模式之模板方法详解
2015/03/04 Javascript
jQuery实现锚点scoll效果实例分析
2015/03/10 Javascript
微信小程序  TLS 版本必须大于等于1.2问题解决
2017/02/22 Javascript
动态统计当前输入内容的字节、字符数的实例详解
2017/10/27 Javascript
Python针对给定字符串求解所有子序列是否为回文序列的方法
2018/04/21 Python
python的常用模块之collections模块详解
2018/12/06 Python
Python multiprocessing多进程原理与应用示例
2019/02/28 Python
基于python if 判断选择结构的实例详解
2019/05/06 Python
Python Django中间件,中间件函数,全局异常处理操作示例
2019/11/08 Python
python将三维数组展开成二维数组的实现
2019/11/30 Python
Django模板之基本的 for 循环 和 List内容的显示方式
2020/03/31 Python
深入理解Python 多线程
2020/06/16 Python
详解CSS3的perspective属性设置3D变换距离的方法
2016/05/23 HTML / CSS
canvas中普通动效与粒子动效的实现代码示例
2019/01/03 HTML / CSS
澳大利亚在线购买儿童玩具:Toy Universe
2017/12/28 全球购物
微软台湾官方网站:Microsoft台湾
2018/08/15 全球购物
大学英语演讲稿(中英文对照)
2014/01/14 职场文书
中学社团活动总结
2015/05/07 职场文书
军事博物馆观后感
2015/06/05 职场文书
孩子满月酒答谢词
2015/09/30 职场文书
2016年安全月活动总结
2016/04/06 职场文书
职场新人知识:如何制定一份合理的工作计划?
2019/09/11 职场文书
golang实现浏览器导出excel文件功能
2022/03/25 Golang
python套接字socket通信
2022/04/01 Python
Python OpenCV超详细讲解读取图像视频和网络摄像头
2022/04/02 Python