浅谈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:socket传输大文件示例
Jan 18 Python
python安装Scrapy图文教程
Aug 14 Python
python中的字典操作及字典函数
Jan 03 Python
python如何把嵌套列表转变成普通列表
Mar 20 Python
python实现淘宝秒杀脚本
Jun 23 Python
python实现五子棋游戏
Jun 18 Python
python中将两组数据放在一起按照某一固定顺序shuffle的实例
Jul 15 Python
Django静态资源部署404问题解决方案
May 11 Python
通过实例了解Python异常处理机制底层实现
Jul 23 Python
正确的理解和使用Django信号(Signals)
Apr 14 Python
Python何绘制带有背景色块的折线图
Apr 23 Python
python自动获取微信公众号最新文章的实现代码
Jul 15 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函数
2010/02/16 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(八)
2014/06/23 PHP
教你如何开启shopnc b2b2c 伪静态
2014/10/21 PHP
PHP错误Warning:mysql_query()解决方法
2015/10/24 PHP
实现WordPress主题侧边栏切换功能的PHP脚本详解
2015/12/14 PHP
Laravel访问出错提示:`Warning: require(/vendor/autoload.php): failed to open stream: No such file or di解决方法
2019/04/02 PHP
Extjs学习笔记之八 继承和事件基础
2010/01/08 Javascript
DOM 中的事件处理介绍
2012/01/18 Javascript
jquery 元素控制(追加元素/追加内容)介绍及应用
2013/04/21 Javascript
jquery实现邮箱自动补全功能示例分享
2014/02/17 Javascript
jquery实现标签上移、下移、置顶
2015/04/26 Javascript
jquery处理checkbox(复选框)是否被选中实例代码
2017/06/12 jQuery
详解Vue的computed(计算属性)使用实例之TodoList
2017/08/07 Javascript
ReactJS实现表单的单选多选和反选的示例
2017/10/13 Javascript
javascript原生封装一个淡入淡出效果的函数测试实例代码
2018/03/19 Javascript
Node.js 使用AngularJS的方法示例
2018/05/11 Javascript
arctext.js实现文字平滑弯曲弧形效果的插件
2019/05/13 Javascript
vue样式穿透 ::v-deep的具体使用
2020/06/04 Javascript
vue 实现超长文本截取,悬浮框提示
2020/07/29 Javascript
原生js实现照片墙效果
2020/10/13 Javascript
用Python编写一个简单的俄罗斯方块游戏的教程
2015/04/03 Python
Python3实现的简单验证码识别功能示例
2018/05/02 Python
python读写LMDB文件的方法
2018/07/02 Python
Python通过TensorFlow卷积神经网络实现猫狗识别
2019/03/14 Python
Python操作多维数组输出和矩阵运算示例
2019/11/28 Python
关于jupyter打开之后不能直接跳转到浏览器的解决方式
2020/04/13 Python
Python操作MySQL数据库的示例代码
2020/07/13 Python
一款纯css3实现的鼠标经过按钮特效教程
2014/11/09 HTML / CSS
CSS3 3D酷炫立方体变换动画的实现
2019/03/26 HTML / CSS
HTML5仿微信聊天界面、微信朋友圈实例代码
2018/01/29 HTML / CSS
澳大利亚药房在线:ThePharmacy
2017/10/04 全球购物
英国No.1体育用品零售商:SportsDirect.com
2019/10/16 全球购物
《一本男孩子必读的书》教学反思
2014/02/19 职场文书
幼儿园感恩节活动总结
2015/03/24 职场文书
调任通知
2015/04/21 职场文书
使用Ajax实现无刷新上传文件
2022/04/12 Javascript