浅谈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赋值操作方法分享
Mar 23 Python
Python中str.format()详解
Mar 12 Python
Linux下多个Python版本安装教程
Aug 15 Python
Python使用pickle模块储存对象操作示例
Aug 15 Python
python实现K近邻回归,采用等权重和不等权重的方法
Jan 23 Python
对Django 中request.get和request.post的区别详解
Aug 12 Python
Python使用百度api做人脸对比的方法
Aug 28 Python
详解使用django-mama-cas快速搭建CAS服务的实现
Oct 30 Python
Python3操作读写CSV文件使用包过程解析
Apr 10 Python
python3 中使用urllib问题以及urllib详解
Aug 03 Python
最新pycharm安装教程
Nov 18 Python
详解pandas赋值失败问题解决
Nov 29 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
支持png透明图片的php生成缩略图类分享
2015/02/08 PHP
php更新cookie内容的详细方法
2019/09/30 PHP
TP5框架实现签到功能的方法分析
2020/04/05 PHP
JavaScript Event学习第十章 一些可替换的事件对
2010/02/10 Javascript
解决jquery操作checkbox火狐下第二次无法勾选问题
2014/02/10 Javascript
Javascript浮点数乘积运算出现多位小数的解决方法
2014/02/17 Javascript
利用JavaScript检测CPU使用率自己写的
2014/03/22 Javascript
jQuery实现向下滑出的平滑下拉菜单效果
2015/08/21 Javascript
JavaScript基础知识点归纳(推荐)
2016/07/09 Javascript
概述javascript在Google IE中的调试技巧
2016/11/24 Javascript
vue之数据交互实例代码
2017/06/16 Javascript
Bootstrap table使用方法记录
2017/08/23 Javascript
canvas轨迹回放功能实现
2017/12/20 Javascript
基于react后端渲染模板引擎noox发布使用
2018/01/11 Javascript
基于node下的http小爬虫的示例代码
2018/01/11 Javascript
详解Python实现多进程异步事件驱动引擎
2017/08/25 Python
详解Python开发中如何使用Hook技巧
2017/11/01 Python
python调用OpenCV实现人脸识别功能
2018/05/25 Python
Python 中的lambda函数介绍
2018/10/10 Python
python 使用poster模块进行http方式的文件传输到服务器的方法
2019/01/15 Python
Python中类的创建和实例化操作示例
2019/02/27 Python
opencv与numpy的图像基本操作
2019/03/08 Python
Python基本语法之运算符功能与用法详解
2019/10/22 Python
Python imutils 填充图片周边为黑色的实现
2020/01/19 Python
python热力图实现简单方法
2021/01/29 Python
css3 box-sizing属性使用参考指南
2013/01/08 HTML / CSS
CSS3 实现footer 固定在底部(无论页面多高始终在底部)
2019/10/15 HTML / CSS
英国领先的鞋类零售商和顶级品牌的官方零售商:Wynsors
2020/02/17 全球购物
什么是View State?
2013/01/27 面试题
专家推荐信范文
2015/03/26 职场文书
一篇合格的广告文案,其主要目的是什么?
2019/07/12 职场文书
Nginx解决403 forbidden的完整步骤
2021/04/01 Servers
25张裸眼3D图片,带你重温童年的记忆,感受3D的魅力
2022/02/06 杂记
Oracle用户管理及赋权
2022/04/24 Oracle
Java实现带图形界面的聊天程序
2022/06/10 Java/Android
使用CSS自定义属性实现骨架屏效果
2022/06/21 HTML / CSS