浅谈Python3多线程之间的执行顺序问题

 更新时间:2020年05月02日 10:10:36   作者:天外归云  
这篇文章主要介绍了浅谈Python3多线程之间的执行顺序问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

一个多线程的题:定义三个线程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绘制数据动态图的方法详解

    这篇文章主要为大家详细介绍了如何利用Python语言绘制好看的数据动态图,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手尝试一下
    2022-07-07
  • Python登录系统界面实现详解

    Python登录系统界面实现详解

    这篇文章主要介绍了Python登录系统界面实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,,需要的朋友可以参考下
    2019-06-06
  • Pytorch 实现计算分类器准确率(总分类及子分类)

    Pytorch 实现计算分类器准确率(总分类及子分类)

    今天小编就为大家分享一篇Pytorch 实现计算分类器准确率(总分类及子分类),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-01-01
  • 在pycharm中实现删除bookmark

    在pycharm中实现删除bookmark

    今天小编就为大家分享一篇在pycharm中实现删除bookmark,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • pandas groupby()的使用小结

    pandas groupby()的使用小结

    在数据分析中,经常会用到分组,可用函数pandas中的groupby(),本文就来介绍一下pandas groupby()的使用小结,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • Python Setuptools的 setup.py实例详解

    Python Setuptools的 setup.py实例详解

    setup.py是一个 python 文件,它的存在表明您要安装的模块/包可能已经用 Setuptools 打包和分发,这是分发 Python 模块的标准。 它的目的是正确安装软件,本文给大家讲解Python Setuptools的 setup.py感兴趣的朋友跟随小编一起看看吧
    2022-12-12
  • Python Numpy中数据的常用保存与读取方法

    Python Numpy中数据的常用保存与读取方法

    这篇文章主要介绍了Python Numpy中数据的常用保存与读取方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • python正则表达式match和search用法实例

    python正则表达式match和search用法实例

    这篇文章主要介绍了python正则表达式match和search用法,实例分析了正则表达式中match和search的功能、定义及相关使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • 在Python中处理字符串之ljust()方法的使用简介

    在Python中处理字符串之ljust()方法的使用简介

    这篇文章主要介绍了在Python中处理字符串之ljust()方法的使用,是Python学习中的基础知识,需要的朋友可以参考下
    2015-05-05
  • pygame.display.flip()和pygame.display.update()的区别及说明

    pygame.display.flip()和pygame.display.update()的区别及说明

    这篇文章主要介绍了pygame.display.flip()和pygame.display.update()的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03

最新评论