浅谈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函数的笔记整理
Apr 07 Python
python算法表示概念扫盲教程
Apr 13 Python
python web基础之加载静态文件实例
Mar 20 Python
Python之用户输入的实例
Jun 22 Python
Python读取txt某几列绘图的方法
Oct 14 Python
Python实现正则表达式匹配任意的邮箱方法
Dec 20 Python
python识别图像并提取文字的实现方法
Jun 28 Python
Python搭建Spark分布式集群环境
Jul 05 Python
Python unittest框架操作实例解析
Apr 13 Python
Keras loss函数剖析
Jul 06 Python
Django返回HTML文件的实现方法
Sep 17 Python
python3.9实现pyinstaller打包python文件成exe
Dec 13 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中的超全局变量
2006/10/09 PHP
Yii中CGridView禁止列排序的设置方法
2016/07/12 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
jQuery 选择器详解
2015/01/19 Javascript
javascript实现类似于新浪微博搜索框弹出效果的方法
2015/07/27 Javascript
JS实现带关闭功能的阿里妈妈网站顶部滑出banner工具条代码
2015/09/17 Javascript
JS身份证信息验证正则表达式
2017/06/12 Javascript
关于Vue背景图打包之后访问路径错误问题的解决
2017/11/03 Javascript
vue+vuex+axios+echarts画一个动态更新的中国地图的方法
2017/12/19 Javascript
Vue下拉框回显并默认选中随机问题
2018/09/06 Javascript
JavaScript实现简单音乐播放器
2020/04/17 Javascript
通过vue写一个瀑布流插件代码实例
2019/09/07 Javascript
详解ES6数组方法find()、findIndex()的总结
2020/05/12 Javascript
JS原型对象操作实例分析
2020/06/06 Javascript
[02:48]DOTA2英雄基础教程 暗夜魔王
2013/12/12 DOTA
[01:13:01]2018DOTA2亚洲邀请赛 4.4 淘汰赛 TNC vs VG 第三场
2018/04/05 DOTA
Python读取ini文件、操作mysql、发送邮件实例
2015/01/01 Python
python面向对象_详谈类的继承与方法的重载
2017/06/07 Python
python中yaml配置文件模块的使用详解
2018/04/27 Python
Python基于SMTP协议实现发送邮件功能详解
2018/08/14 Python
使用Django开发简单接口实现文章增删改查
2019/05/09 Python
python 判断三个数字中的最大值实例代码
2019/07/24 Python
python中的逆序遍历实例
2019/12/25 Python
Python Selenium 设置元素等待的三种方式
2020/03/18 Python
使用opencv识别图像红色区域,并输出红色区域中心点坐标
2020/06/02 Python
值得收藏的HTML5资源(学习html5的朋友可以收藏下)
2010/07/20 HTML / CSS
预订全球最佳旅行体验:Viator
2018/03/30 全球购物
adidas马来西亚官网:adidas MY
2020/09/12 全球购物
PHP面试题大全
2015/10/16 面试题
中软Java笔试题
2012/11/11 面试题
法定代表人授权委托书
2014/04/04 职场文书
2014年学生党支部工作总结
2014/12/20 职场文书
佛光寺导游词
2015/02/10 职场文书
电话营销开场白
2015/05/29 职场文书
环境卫生标语
2015/08/03 职场文书
Python入门之基础语法详解
2021/05/11 Python