Python 3 Thread 模块的学习理解

2023-11-19

一、概述:

	Thread 类描绘了一个单独运行的控制线程活动,有两种方式指定这种活动,通过一个可调用对象的构造函数,或者通过覆盖子类run()方法。没有其他的方法应在子类中重写。换句话说,只有推翻这个类的__init__()和run()方法。
	一旦Thread这个对象被创建,这个对象的活动必须通过 thread 的start()方法启动。这将唤起run()方法在单独的线程控制。
    一旦线程的活动开始,这个线程的状态就是“alive”。当run()方法结束时才会结束“alive“状态。我们也可以直接运行 is_alive()方法判断这个进程的状态时"alive".
    一个线程可以调用另一个线程的join()方法。这种叫做阻塞调用线程,直到其join()方法叫做线程终止。
   一个线程的名字是通过构造器传递的,也可以通过name属性修改或者读取。
    一个线程可以标记为守护线程(daemon thread),这种被标记的线程时当python程序退出时它才退出。它的最初的值时当线程被创建时继承下来的。 这个标志可以通过daemon 或者daemone constructor变量设定。
    提示:daemon thread 是当程序关闭的时候立即被中断的。它时不会被适宜的释放。 如果你想让你的线程适宜的停止。可以让它non-daemonic 或者用一些适当的信号机制。
   有可能存在'dummy thread objects'(哑线程对象)被创建。这些线程对应于'alien threads'(外部线程),它们在Python的线程模型之外被启动,像直接从C语言代码中启动。哑线程对象只有有限的功能,它们总是被认为是活动的,守护线程,不能使用join()方法。它们从不能被删除,它无法监测到外部线程的中止。

*二、Thread 中常用的方法和变量

1.start()
启动线程活动。
2.run()
这个方法描述线程的活动,可以在子类中覆盖这个方法。
3.join()
python的Thread类中还提供了join()方法,使得一个线程可以等待另一个线程执行结束后再继续运行。这个方法还可以设定一个timeout参数,避免无休止的等待。因为两个线程顺序完成,看起来象一个线程,所以称为线程的合并.
通过传给join一个参数来设置超时,也就是超过指定时间join就不在阻塞进程。而在实际应用测试的时候发现并不是所有的线程在超时时间内都结束的,而是顺序执行检验是否在time_out时间内超时,例如,超时时间设置成2s,前面一个线程在没有完成的情况下,后面线程执行join会从上一个线程结束时间起再设置2s的超时。
4.name()
5.getname(0
6.setname()
7.ident()
8.is_alive()
9.daemon
一个布尔值,指示是否该线程是damemon thread(TRUE)或不(假)。这之前必须设置start()叫,否则运行时出错了。它的初始值是从创建线程继承;主线程不是一个守护线程,因此在守护=假主线程默认创建的所有线程。
整个Python程序退出时没有活着的非守护线程离开。
10.isDaemon()
11. setDaemon()

三、 threading
threading 是比_thread 更高级的模块
1、方法:
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
这个构造函数通常会用一些关键字参数,下面就了解下这些关键字:
group :这个变量作为保留变量,是为了以后扩展用的,暂时可以不用考虑。
target: 是通过run()方法调用的可调用对象。默认为无,这意味着什么都不做。
name:线程的名字。默认情况下,一个唯一的名称是”thread-n”,的形式,其中n是一个小的十进制数。
args:元组参数,为target所调用的。
kwargs:关键字参数的字典,为target所调用的。
daemon: 设置daemon是否daemon 如果没有显示设置,daemon的属性时从当前线程继承。
如果子类重写此构造函数,它必须确保在做别的事情之前调用基类的构造函数(thread.init()。

2、这模块定义了如下的方法
1,threading.active_count()
这个函数返回当前线程的个数,这个程序的值也等于列表
enumerate()的长度。
2.current_thread()
返回当前的线程对象。如果调用的线程不是通过threading 这个
模块创建的,那么返回的是一个有限功能的dummy thread
objects’(哑线程对象。
3.threading.get_ident()
返回当先线程的索引,这个索引是一个非零的整数。
4.threading.enumereate()
返回当前运行线程的列表。这个列表包含dummy thread
objects’(哑线程对象,daemon thread’(守护线程),和那些主线程。
这些线程的状态可能时已经运行的,还没有运行的。
5.threading.main_thread()
返回主线程,正常情况下,主线程就是python 解释器运行时开始
的那个线程。
6.threading.settrace(func)
当开始调用threading 模块的时候设定 跟踪函数(trace function )
7.threading.setprofile(func)
设定 profile function
8,threading.stack_size(【size】)
返回创建新线程时线程Stack的大小。可选的数值size用于随后创建线程时使用,这个
数字必须是零,或者大于32768(32kb)的整数。在未允许的情况下改变线程堆的大小
会唤醒Runtimerror。如果这个线程堆的大小是无效的,那么会唤醒ValueError错误,并
且线程堆的大小将不会设定。 32kb这个size是最小允许的线程堆大小,这样就可以保
证线程堆有足够的大小在python解释器中安全的运行。有些平台对于线程堆的大小
有特殊的限制。

3、这个模块也定义了一些常量。
如:threading.TIMEOT_MAX
1.信号量
也提供acquire方法和release方法,每当调用acquire方法的时候,如果内部计
数器大于0,则将其减1,如果内部计数器等于0,则会阻塞该线程,知道有线程调
用了release方法将内部计数器更新到大于1位置。
class threading.Sempaphore(value = 1) --限制资源的并发访问。
semaphore 是一个内部的计数器,它会随着acquire()的请求减小,也会随着release()的
释放增加。这个计数器的值不会小于零,当acquier() 发现计数器的值为0时,那么当前
对象会等待直到其他对象release()为止。
acquier(blocking = True ,timeout = None)
release()
在这里插入图片描述
2.class threading.Timer(interval,function,args = None ,kwargs = None)
创建一个时间对象,设定一个函数于多长时间后运行。
Timer.start()
Timer.cancel()

3.class.threading.Barrier(parties,action = None ,timeout = None)
wait(timeout = None)
这个类对那些固定数量的,需要相互等待的线程。提供了一个简单的同步机制。
reset()
abort()
parties
n_waiting
broken

4 ,threading的Lock类,用该类的acquire函数进行加锁,用realease函数进行解锁

    当一个线程调用锁的acquire()方法获得锁时,锁就进入“locked”状态。每次只有一个线程可以获得锁。如果此时另一个线程试图获得这个锁,该线程就会变为“blocked”状态,称为“同步阻塞”(参见多线程的基本概念)。 

直到拥有锁的线程调用锁的release()方法释放锁之后,锁进入“unlocked”状态。线程调度程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入运行(running)状态。

#lock = threading.Lock()
#lock.acquire()
#locke.release()

5, RLock Objects( 如果同一个线程的不同代码需要“重新获得“锁,再这种情况下则需要使用RLock)
class thread.RLock

6,Condition Objects
使用Condition对象可以在某些事件触发或者达到特定的条件后才处理数据,Condition除了具有Lock对象的acquire方法和release方法外,还有wait方法、notify方法、notifyAll方法等用于条件处理。

threading.Condition([lock]):创建一个condition,支持从外界引用一个Lock对象(适用于多个condtion共用一个Lock的情况),默认是创建一个新的Lock对象。

acquire()/release():获得/释放 Lock

wait([timeout]):线程挂起,直到收到一个notify通知或者超时(可选的,浮点数,单位是秒s)才会被唤醒继续运行。wait()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。调用wait()会释放Lock,直至该线程被Notify()、NotifyAll()或者超时线程又重新获得Lock.

notify(n=1):通知其他线程,那些挂起的线程接到这个通知之后会开始运行,默认是通知一个正等待该condition的线程,最多则唤醒n个等待的线程。notify()必须在已获得Lock前提下才能调用,否则会触发RuntimeError。notifhri()不会主动释放Lock。

notifyAll(): 如果wait状态线程比较多,notifyAll的作用就是通知所有线程(这个一般用得少

举例:
try:
import threading
except ImportError:
import dummy_threading

def worker(num,num2,key):
print (“WORKER is :”,num,num,key)

for i in range(5):
t = threading.Thread(target = num, args = (i,i+1),kwargs = {“key”:i+2,})
t.start()

我们创建实例t ,将target 设为函数woker,而此时 *args,和**kwargs 都作为woker()的入口参数。
这个函数的结果为:
WORKER is : 0 0 2
WORKER is : 1 1 3
WORKER is : 2 2 4
WORKER is : 3 3 5
WORKER is : 4 4 6
——---------------------------------------------------
例2:

try:
import threading
except ImportError:
import dummy_threading

import time

def worker():
print (threading.current_thread().getName(),"starting ")
time.sleep(2)
print (threading.current_thread().getName(),“ending”)

def my_service():
print (threading.current_thread().getName(),“starting”)
time.sleep(3)
print (threading.current_thread().getName(),“ending”)

t = threading.Thread(target = worker,name = “worker”)
t1 = threading.Thread(target = my_service ,name = “my_service”)
t2 = threading.Thread(target = worker)
t.start()
t1.start()
t2.start()
–输出:
worker starting
my_service starting
Thread-1 starting
worker ending
Thread-1 ending
my_service ending
用 current_thread()返回当前运行的线程,用getName()方法获得线程的名字,我们可以通过通过setName()修改名字。如果当我们创建实例时没有设定线程的名字,那么相称的名字的格式为“Thread-N”,N为非零的整数。

例3:
守护线程和非守护线程:
守护线程可以一直运行而不阻塞主程序推出。如果一个服务器无法用一种容易的方法来中断线程,或者希望线程工作到一半时终止而不损失或者破坏数据,对于这些服务使用守护线程就很有用。要设置一个守护线程可以用setDaemin(),并提供参数True。

要等待一个守护线程完成工作,需要使用join()方法。

————————————————————————————————

例四:threading.Lock

import time
import threading
import random
class Counter():
def init(self,start = 0):
self.lock = threading.Lock()
self.value = start
def increment(self):
self.lock.acquire()
try:
self.value = self.value + 1
finally:
self.lock.release()
def worker©:
pause = random.random()
print (“starting”,threading.current_thread().getName())
print(“Sleeping :”,pause)
time.sleep(pause)
c.increment()
print(“Ending”)

c = Counter()

for i in range(5):
t = threading.Thread(target = worker ,args = (c,))
t.start()
mainThread = threading.current_thread()

for t in threading.enumerate():
if t is not mainThread:
t.join()

print (“counter”,c.value)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 3 Thread 模块的学习理解 的相关文章

随机推荐

  • Hx711调试过程

    1 体重板子最开始出现的问题 无法下载程序 指示灯不亮 解决办法 检查电源复位晶振 发现晶振还有 boot键坏了 2 问题 下载进程序以后 板子通过串口发到电脑上的数据不变 解决办法 先是查了关于HX711的各种资料 了解到 HX711芯片
  • pycharm内存不足时如何修改设置?

    Help gt Find Action gt type VM Options gt Click Edit Custom VM Options Pycharm 2016 2 will open the appropriate vmoption
  • MFC中操作Word文档

    首先我们需要导入word类库 电脑上需要安装了word 左击项目 点击类向导 添加类 C 选择类型库中的MFC类 本文章案例可点击下载 然后选择文件 位置选择从office安装目录中找到MSWORD OLB文件 然后点击 gt gt 添加所
  • 源码探索-ArrayList

    ArrayList 继承与实现关系 数组的相关属性 ArrayList底层是一个Object 数组 既然是数组 那么底层的工具类大多是会用到Arrays工具类去实现 函数探索 来看看构造函数 有三个构造函数 分别对应不同的生成内容 来看看添
  • linux 2.6.30 内核编译 提示 ‘make[1]: *** [arch/x86/vdso/vdso.so.dbg] Error 1’ 错误

    linux 2 6 30 编译出现如下错误 解决方案 打开 linux 2 6 30 arch x86 vdso Makefile 文件 1 修改28行 将 m elf x86 64 修改为 m64 2 修改72行 将 m elf i386
  • 语音识别学习记录 [再谈频率混叠(定量分析、离散采样后频谱的周期延拓)]

    前几天在语音识别学习记录 传说中的频率混叠和Nyquist定理 定性理解 中简单理解了一下频率混叠的原因 但是也发现了很多不明白的问题 1 为什么信号经过傅里叶变换后在频域是关于y轴对称的 这个问题的回答已经写在语音识别学习记录 信号经傅里
  • vue的指令

    Vue 的指令 一 Vue 的指令 1 指令的概念 指令 Directives 是 vue 为开发者提供的模板语法 用于辅助开发者渲染页面的基本结构 vue 中的指令按照不同的用途可以分为如下 6 大类 内容渲染指令 属性绑定指令 事件绑定
  • SQL 查询指定行数的数据。

    今天遇到一个关于 查询指定行数的数据 的sql查询语句问题 突然发现以前没怎么接触过 刚才想起来了 赶紧看了下文档 又上网搜了下 有了下面的东西 不知道有没有什么地方不对 oracle 先看一下文档中关于any和all的例子 很不错噢 An
  • Pytorch 深度强化学习模型训练速度慢

    最近一直在用Pytorch来训练深度强化学习模型 但是速度一直很慢 Gpu利用率也很低 一 起初开始在训练参数 batch size 200 graph size 40 epoch size 100000 训练速度一个epoch要4h 人麻
  • node学习openai库入门及使用(一)

    第一章 node学习openai库入门及使用 一 文章目录 第一章 node学习openai库入门及使用 一 前言 一 node js的openai库是什么 二 使用步骤 1 引入库 2 发送请求 总结 前言 众所周知 目前chatgpt已
  • cuda8.0使用nvcc编译程序出现warning:The 'compute_20', 'sm_20', and 'sm_21' architectures are deprecated的解决办法

    初学CUDA 使用的NVIDIA显卡是Tesla K80 安装的是cuda8 0 写了一个简单的测试程序 使用nvcc编译 指令如下 nvcc cudaPrintDeviceInfo cu o cudaPrintDeviceInfo 本以为
  • docker快速学习--docker compose服务编排--06

    一 服务编排 1 1 概念 按照一定的业务规则批量管理容器 1 3 问题 微服务架构的应用系统中一般包含若干个微服务 每个微服务一般都会部署多个实例 如果每个微服务都要手动启停 维护的工作量会很大 1 要从Dockerfile build
  • go踩坑——no required module provides package go.mod file not found in current directory or any parent

    背景 准备运行下面代码 package main import github com gin gonic gin func main 创建一个默认的路由引擎 r gin Default GET 请求方式 hello 请求的路径 当客户端以G
  • C++实现复数类

    主要还是练习封装 做一个demo 下一步会实现string类 include
  • ECCV 2022

    作者丨人脸人体重建 来源丨人脸人体重建 编辑丨极市平台 极市导读 本文围绕3D人脸重建的评估方式进行了重新的思考和探索 作者团队通过构建新数据集RELAY 囊括了更丰富以及更高质量的脸部区域信息 并借助新的流程对先前的数十个重建算法 3DM
  • 题解模板

    题目链接 题目描述 输入描述 输出描述 示例1 输入 输出 示例2 输入 输出 说明 解决思路 总结结论 已知条件 思路里程 实现过程 代码
  • 一些大厂的开源平台

    百度 http fex baidu com http efe baidu com 饿了么 https fe ele me 腾讯 http www alloyteam com 美团 https tech meituan com 滴滴 http
  • mongodb按照字段模糊查询方法

    数据库直接查询 db student find name regex jack options i db student find name regex jack i db student find name jack i 开源组件使用 g
  • 随手写系列——写一个凯撒密码转换页面

    文章目录 先展示效果 H5编写 C3编写 JS编写 方法一 过程版 JS编写 方法二 对象版 代码获取 先展示效果 因为主要是实现功能 所以CSS写的很粗糙 H5编写 基础结构如下 先构成最外面的大盒子 box 然后 inner gt p装
  • Python 3 Thread 模块的学习理解

    一 概述 Thread 类描绘了一个单独运行的控制线程活动 有两种方式指定这种活动 通过一个可调用对象的构造函数 或者通过覆盖子类run 方法 没有其他的方法应在子类中重写 换句话说 只有推翻这个类的 init 和run 方法 一旦Thre