IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 阅读Python官网文档对threading.Thread线程的介绍 -> 正文阅读

[Python知识库]阅读Python官网文档对threading.Thread线程的介绍

Python线程模块threading:https://docs.python.org/zh-cn/3/library/threading.html

1、Python的threading模块定义了许多类,该模块的设计基于Java的线程模型。但是,在Java里面,锁和条件变量是每个对象的基础特性,而在Python里面,这些被独立成了单独的对象(threading.Lock()锁,threading.Condition()条件变量)。Python 的?Thread?类只是 Java 的 Thread 类的一个子集;目前还没有优先级,没有线程组,线程还不能被销毁、停止、暂停、恢复或中断。Java 的 Thread 类的静态方法在实现时会映射为模块级函数。

2、threading.Thread类表示运行在一个独立控制的线程中的一项活动。有两种方式指定活动:传递可调用对象给threading.Thread构造函数,也就是threading.Thread(group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None)中的target。或在threading.Thread的子类中覆盖run()方法。子类出了构造方法外不该覆盖其他方法。换句话说,子类只能覆盖threading.Thread的__init__()方法(都继承了当然要覆盖并传递调用父类构造)和run()方法。

对my_thread1 = threading.Thread(target=my_func)的用法,没有继承threading.Thread类,则threading.Thread.run()方法默认调用self.target()。如果继承了threading.Thread类,当然可以在覆盖的DerivedThread.__init__(target=my_func,args=my_args,kwargs=my_kwargs)构造器中传递target并首先调用threading.Thread.__init__(target=myfunc,args=my_args,kwargs=my_kwargs),也有机会重写run方法。

标准的(即thread.Thread.run)?run()?方法会对作为?target?参数传递给该对象构造器的可调用对象(如果存在)发起调用,并附带从?args?和?kwargs?参数分别获取的位置和关键字参数。

3、当线程对象一但被创建,其活动一定会因调用线程的?start()?方法开始。这会在独立的控制线程(也就是启动的子线程)调用?run()?方法。

4、一旦线程活动开始,该线程会被认为是 '存活的' 。当它的?run()?方法终结了(不管是正常的还是抛出未被处理的异常),就不是'存活的'。?is_alive()?方法用于检查线程是否存活。

>>> cur_thread = threading.current_thread()
>>> cur_thread.is_alive()
True

5、其他线程(相对的主线程)可以调用一个线程(子线程引用)的?join()?方法。这会阻塞调用该方法的线程(相对的主线程),直到被调用?join()?方法的线程(子线程)终结。

6、线程有名字。名字可以传递给构造函数,也就是threading.Thread(group=None, target=None, name=None, args=(), kwargs=None, *, daemon=None)中的name,也可以通过?name?属性读取或者修改。

>>> cur_thread.name
'MainThread'

7、如果?run()?方法引发了异常,则会调用?threading.excepthook()?来处理它。 在默认情况下,threading.excepthook()?会静默地忽略?SystemExit

8、一个线程可以被标记成一个“守护线程”。 这个标识的意义是,当剩下的线程都是守护线程时,整个 Python 程序将会退出。 初始值继承于创建线程。 这个标识可以通过?daemon?特征属性或者?daemon?构造器参数来设置。

注解:守护线程在程序关闭时会突然关闭。他们的资源(例如已经打开的文档,数据库事务等等)可能没有被正确释放。如果你想你的线程正常停止,设置他们成为非守护模式并且使用合适的信号机制,例如:?Event

守护线程我理解为比如监视线程、消费者线程,当生产者线程都结束时,剩下的监视线程、消费者线程都没有存在的必要,可以立即结束了。

有个 "主线程" 对象;这对应Python程序里面初始的控制线程。它不是一个守护线程。

>>> cur_thread.daemon
False
>>> cur_thread.daemon=True
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/haypin/miniconda3/lib/python3.9/threading.py", line 1127, in daemon
    raise RuntimeError("cannot set daemon status of active thread")
RuntimeError: cannot set daemon status of active thread

9、"虚拟线程对象" 是可以被创建的。这些是对应于“外部线程”的线程对象(我理解是对外部线程的引用,但Python对其封装的方法有限,不能监测外来线程的终结),它们是在线程模块外部启动的控制线程,例如直接来自C代码。虚拟线程对象功能受限;他们总是被认为是存活的和守护模式,不能被?join()?。因为无法检测外来线程的终结,它们永远不会被删除。

10、class?threading.Thread(group=None,?target=None,?name=None,?args=(),?kwargs={},?*,?daemon=None)

调用这个构造函数时,必需带有关键字参数。参数如下:

group?应该为?None;为了日后扩展?ThreadGroup?类实现而保留。

target?是用于?run()?方法调用的可调用对象。默认是?None,表示不需要调用任何方法。

name?是线程名称。默认情况下,由 "Thread-N" 格式构成一个唯一的名称,其中?N?是小的十进制数。

args?是用于调用目标函数的参数元组。默认是?()

kwargs?是用于调用目标函数的关键字参数字典。默认是?{}

如果不是?Nonedaemon?参数将显式地设置该线程是否为守护模式。 如果是?None?(默认值),线程将继承当前线程的守护模式属性。

如果子类型重载了构造函数,它一定要确保在做任何事前,先发起调用基类构造器(Thread.__init__())

10.1 start()

开始线程活动。

它在一个线程里最多只能被调用一次。它安排对象的?run()?方法在一个独立的控制进程中调用。

如果同一个线程对象中调用这个方法的次数大于一次,会抛出?RuntimeError?。

10.2 run()

代表线程活动的方法。

你可以在子类型里重载这个方法。 标准的?run()?方法会对作为?target?参数传递给该对象构造器的可调用对象(如果存在)发起调用,并附带从?args?和?kwargs?参数分别获取的位置和关键字参数

10.3??join(timeout=None)?

等待,直到线程终结。这会阻塞调用这个方法的线程(相对主线程),直到被调用?join()?的线程终结 -- 不管是正常终结还是抛出未处理异常 -- 或者直到发生超时,超时选项是可选的。

当?timeout?参数存在而且不是?None?时,它应该是一个用于指定操作超时的以秒为单位的浮点数(或者分数)。因为?join()?总是返回?None?,所以你一定要在?join()?后调用?is_alive()?才能判断是否发生超时 -- 如果线程仍然存活,则?join()?超时(调用join()处阻塞因超时而停止阻塞,才能执行到后面的is_alive(),此时线程大概率还活着,一旦活着那肯定是超时了)。

当?timeout?参数不存在或者是?None?,这个操作会阻塞直到线程终结。

一个线程可以被?join()?很多次(指同一主线程的多个函数都超时阻塞同一个子线程,或多个线程阻塞等待同一个线程,一个线程的多个函数非超时阻塞同一个子线程是没有意义的)

如果尝试加入当前线程会导致死锁(同一线程自我阻塞、两个线程相互阻塞,后者指:主线程在构造子线程时将自身引用传递给子线程,子线程的线程函数中有阻塞等待传入的父线程,然后父线程再阻塞等等待这个子线程),?join()?会引起?RuntimeError?异常。如果尝试?join()?一个尚未开始的线程,也会抛出相同的异常

>>> cur_thread.join()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/haypin/miniconda3/lib/python3.9/threading.py", line 1030, in join
    raise RuntimeError("cannot join current thread")
RuntimeError: cannot join current thread

10.4?name

只用于识别的字符串。它没有语义。多个线程可以赋予相同的名称。 初始名称由构造函数设置。

10.5 ident

这个线程的 '线程标识符',如果线程尚未开始则为?None?。这是个非零整数。参见?get_ident()?函数。当一个线程退出而另外一个线程被创建,线程标识符会被复用。即使线程退出后,仍可得到标识符。

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 11:36:25  更:2021-07-25 11:38:00 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 23:04:07-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码