浅谈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的Django框架中实现Hacker News的一些功能
Apr 17 Python
Python中的条件判断语句与循环语句用法小结
Mar 21 Python
Python爬取网易云音乐上评论火爆的歌曲
Jan 19 Python
python中numpy包使用教程之数组和相关操作详解
Jul 30 Python
对tensorflow 的模型保存和调用实例讲解
Jul 28 Python
django框架自定义用户表操作示例
Aug 07 Python
python集合比较(交集,并集,差集)方法详解
Sep 13 Python
对于Python深浅拷贝的理解
Jul 29 Python
python爬虫学习笔记之pyquery模块基本用法详解
Apr 09 Python
用python实现前向分词最大匹配算法的示例代码
Aug 06 Python
教你用Python matplotlib库制作简单的动画
Jun 11 Python
利用Python实时获取steam特惠游戏数据
Jun 25 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语法(1)
2006/10/09 PHP
Linux下安装PHP MSSQL扩展教程
2014/10/24 PHP
PHP单例模式定义与使用实例详解
2017/02/06 PHP
php微信开发之关注事件
2018/06/14 PHP
PHP学习记录之常用的魔术常量详解
2019/12/12 PHP
YII2框架中日志的配置与使用方法实例分析
2020/03/18 PHP
window.js 主要包含了页面的一些操作
2009/12/23 Javascript
基于jQuery的消息提示插件 DivAlert之旅(二)
2010/04/01 Javascript
JS案例分享之金额小写转大写
2014/05/15 Javascript
JavaScript代码应该放在HTML代码哪个位置比较好?
2014/10/16 Javascript
深入理解Node.js的HTTP模块
2016/10/12 Javascript
JS实现本地存储信息的方法(基于localStorage与userData)
2017/02/18 Javascript
微信小程序 使用腾讯地图SDK详解及实现步骤
2017/02/28 Javascript
Angular4 中内置指令的基本用法
2017/07/31 Javascript
如何把vuejs打包出来的文件整合到springboot里
2018/07/26 Javascript
Vue程序化的事件监听器(实例方案详解)
2020/01/07 Javascript
Node.js API详解之 console模块用法详解
2020/05/12 Javascript
Python中绑定与未绑定的类方法用法分析
2016/04/29 Python
Python cookbook(数据结构与算法)在字典中将键映射到多个值上的方法
2018/02/18 Python
基于tensorflow加载部分层的方法
2018/07/26 Python
python实现字典嵌套列表取值
2019/12/16 Python
浅谈Python中的异常和JSON读写数据的实现
2020/02/27 Python
Python pip使用超时问题解决方案
2020/08/03 Python
CSS3实现可爱的小黄人动画
2016/07/11 HTML / CSS
Tessabit日本:集世界奢侈品和设计师品牌的意大利精品买手店
2020/01/07 全球购物
2014年元旦感言
2014/03/06 职场文书
中餐厅经理岗位职责
2014/04/11 职场文书
竞选学生会演讲稿
2014/04/25 职场文书
创先争优承诺书
2015/01/20 职场文书
部门主管竞聘书
2015/09/15 职场文书
小学中队委竞选稿
2015/11/20 职场文书
旅游安全责任协议书
2016/03/22 职场文书
pytorch加载预训练模型与自己模型不匹配的解决方案
2021/05/13 Python
Java基础之this关键字的使用
2021/06/30 Java/Android
日本动漫十大公认神作:第五现已全网禁播,《死亡笔记》在榜
2022/03/18 日漫
mybatis 获取更新记录的id
2022/05/20 Java/Android