• 自学Python 51 多线程开发(一)threading模块


    Python​ threading模块

    活动地址:CSDN21天学习挑战赛



      当一个程序在同一时间只能做一件事情时就是单线程程序,这样的程序的功能会显得过于简单,肯定无法满足现实的需求前面学习的程序大多数都是单线程程序,那么究竟什么是多线程呢?能够同时处理多个任务的程序就是多线程程序,多线程程序的功能更加强大,能够满足现实生活中需求多变的情况。Python作为一门面向对象的语言,支持多线程开发功能。在本章中将详细讲解Python多线程开发的基本知识。


    一、线程和进程介绍

      在计算机应用中,线程是程序运行的基本执行单元,当操作系统(不包括单线程的操作系统,如微软早期的 DOS)在执行一个程序时,会在系统中建立一个进程,而在这个进程中,必须至少建立一个线程(这个线程被称为主线程)作为这个程序运行的入口点。因此,在操
    作系统中运行的任何程序都至少有一个主线程。
      进程和线程是现代操作系统中两个必个可少的运行模型。在操作系统中可以有多个进程,这些进程包括系统进程(由操作系统内部建立的进程)和用户进程(由用户程序建立的进程;在一个进程中可以有一个或多个线程。进程和进程之间不会共享内存,也就是说,系统中的进程是在各自独立的内存空间中运行的。而一个进程中的线程可以共享系统分派给这个进程的内存空间。
      线程不仅可以共享进程的内存,而且还拥有一个属于自己的内存空间,这段内存空间也叫作线程栈,是在建立线程时由系统分配的,主要用来保存线程内部所使用的数据,如线程执行函数中所定义的变量。在操作系统将进程分成多个线程后,这些线程可以在操作系统的管理下并发执行,从而极大地提高了程序的运行效率。虽然线程的执行从宏观上看是多个线程同时执行,但是实际上这只是操作系统的障眼法。由于一块CPU同时只能执行一条指令,因此,在拥有一块 CPU的计算机上不可能同时执行两个任务。而操作系统为了能提高程序的运行效率,在一个线程空闲时会撤下这个线程,并且会让其他的线程习来执行,这种方式叫作线程调度。

    二、使用 threading模块

      在Python程序中,可以通过“_thread”和“threading(推荐使用)”这两个模块来处理线程。在 Python3程序中,thread模块已被废弃,Python 官方建议使用threading模块代替。所以,在Python3中不能再使用thread模块,但是为了兼容Python3以前的程序,在 Python3中将thread模块重命名为“_thread"。
      在Python 3程序中,可以通过两个标准库(_thread和 threading)提供对线程的支持。其中“_thread”提供了低级别的、原始的线程以及一个简单的锁,它相比于 threading模块的功能还是比较有限的。在本节的内容中,将详细讲解使用 threading模块的核心知识。

    2.1 threading模块的核心方法

      在 threading模块中,除了包含“ _thread”模块中的所有方法外,还提供了其他核心方法,如下表所示。

    核心方法描述
    threading.currentThread()返回当前的Thread对象,这是一个线程变量。如果调用者控制的线程不是通过threading模块创建的,则返回一个只有有限功能的虚假线程对象
    threading.enumerate()返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程
    threading.activeCount()返回正在运行的线程数量,与len(threading.enumerate())有相同的结果
    threading.main_thread()返回主Thread对象。在正常情况下,主线程是从Python解释器中启动的线程
    threading.settrace(func)为所有从 threading模块启动的线程设置一个跟踪方法。在每个线程的run方法调用之前,func将传递给sys.settrace()
    threading.setprofile(func)为所有从 threading模块启动的线程设置一个 profile()方法。这个 profile()方法将在每个线程的run()方法被调用之前传递给sys.setprofile()

      在 threading模块中,还提供了常量 threading.TIMEOUT_MAX,这个 timeout参数表示阻塞方法(Lock.acquire()、RLock.acquire()和 Condition.wait(),等)允许等待的最长时限,设置超过此值的超时将会引发OverflowError错误。

    2.2 使用 Thread对象

      除了前面介绍的核心方法外,在模块 threading中还提供了类 Thread来外理线程。Thread是 threading模块中最重要的类之一,可以使用它来创建线程:一种是通过继承Thread类,重写它的run方法;另一种是创建一个threading.Thread对象,它的初始化函数( _ init_ )中将可调用对象作为参数传入。类Thed的讲法格式如下所示:

    classthreading.Thread(group=None, LargeteNone,name=None, args=(), kwargs={ }, *,daemon=None)
    
    • 1

      上述参数的具体说明如下表所示。

    参数名称描述
    group应该为None, 用于在实现ThreadGroup类时的未来扩展
    target是将被run()方法调用的可调用对象。默认为None, 表示不调用任何东西
    name是线程的名字。在默认情况下,以"Thread-N" 的形式构造一个唯一的名字, N是一个小的十进制整数
    args是给调用目标的参数元组,默认为0
    kwargs是给调用目标的关键字参数的一个字典,默认为“{}”
    daemon如果其值不是None,则守护程序显式设置线程是否为daemonic.如果值为None(默认值),则属性dacmonic从当前线程继承

      在Python程序中,如果了类覆盖Thread构造函数,则必须保证在对线程做任何事之前调用基类的构造函数(Thread._ init_())。例如在下面的实例中,演示了直接在线程中运行函数的过程。

    import threading
    def zhiyun(x,y):        #定义函教zhiyun()
        for i in range(x,y):        #遍历操作
            print(str(i*i)+';')     #打印输出一个数的平方
    ta = threading.Thread(target=zhiyun,args=(1,6))
    tb = threading.Thread(target=zhiyun,args=(16,21))
    print('数字的平方计算')
    print('数字的平方计算是:')
    ta.start()      #启动第1个线程活动
    tb.start()      #启动第2个线程活动
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

      在上述实例代码中,首先定义函数zhiyun(),然后以线程方式来运行这个函数,并且在每次运行时传递不同的参数。运行后两个子线程会并行执行,可以分别计算出一个数的平方并输出,这两个子线程是交替运行的。

  • 相关阅读:
    Chief Ray and Margin Ray and Principle Ray(主光线和边缘光线)
    MySQL timestamp NOT NULL插入NULL的问题
    vim编译器工具
    前端新手Vue3+Vite+Ts+Pinia+Sass项目指北系列文章 —— 第五章 组件库安装和使用(Element-Plus基础配置)
    51单片机学习:外部中断0实验
    Linux常用命令
    【数据结构与算法】链表
    MySQL单表过大、主从模式、同步模式优化原理
    Maven多模块项目管理小结
    java基础10题
  • 原文地址:https://blog.csdn.net/weixin_46066007/article/details/126182040