Python3 threading模块创建线程(一)

2023-11-03


前言

threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:

  • threading.currentThread(): 返回当前的线程变量。
  • threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
  • threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:

  • run(): 用以表示线程活动的方法。
  • start():启动线程活动。
  • join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
  • isAlive(): 返回线程是否活动的。
  • getName(): 返回线程名。
  • setName(): 设置线程名。
  • 参考文章
  1. python3并发编程(多进程,多线程,多任务) ⭐⭐建议先阅读本篇文章

一、使用 threading 模块创建线程

通过直接从 threading.Thread 继承创建一个新的子类,并实例化后调用 start() 方法启动新线程,即它调用了线程的 run() 方法:

  • 步骤
  1. 创建类,继承自threading.Thread类
  2. 实例化创建的线程类
  3. 调用start()方法 [会自动调用run()方法]
  • 代码如下(示例一):
import threading
import time

exitFlag = 0

# 创建类  继承自threading.Thread类
class myThread (threading.Thread):
    # 注意:不要忘记在子类中初始化父类的方法Thread.__init__(self) 。需要重构 run() 方法来执行多线程的程序。
    def __init__(self, threadID, name, delay): 
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.delay = delay
        
    def run(self):
        print ("开始线程:" + self.name)
        print_time(self.name, self.delay, 5)  # 调用要执行的程序
        print ("退出线程:" + self.name)

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            threadName.exit()  # 线程退出
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

# 创建新线程 ---- 实例化创建的线程类
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()


thread1.join()
thread2.join()
print ("退出主线程")

join()方法只有在你需要等待线程完成然后在做其他事情的时候才是有用的。本例中是主线程等待子线程thread1,thread2运行完毕后再执行print (“退出主线程”)语句。

  • 运行结果
    在这里插入图片描述
  • 注意:不要忘记在子类中初始化父类的方法Thread.init(self) 。需要重构 run() 方法来执行多线程的程序。
  • 代码如下(示例二):

若将print (“退出主线程”)语句放在join()语句之前,相当于join()语句是没有任何作用的

...
...
...
print ("退出主线程")
thread1.join()
thread2.join()

在这里插入图片描述
通过这次实验也不难发现主线程的运行速度是非常快的,优于子线程率先执行结束!

  • 代码如下(示例三):

若注释掉其中的一个join()语句,又会发生什么情况呢?

...
...
...
thread1.join()
# thread2.join()

print ("退出主线程")

在这里插入图片描述
上述结果表明,主线程不需要等待子线程2结束后再输出print()语句,只需要等待子线程1结束后直接输出print()语句。即不管子线程2的状态如何,只要子线程1结束,主线程就输出print()语句。


二、资源独占

  • 案例一
"""
多线程 资源独占
    1、程序中有主线程、子线程,但是多个线程的执行过程,没有顺序。
        那个执行可以执行由CPU管理的!

    2、子线程没有执行结束时,主线程不会退出
       子线程没有执行结束时,主线程中的代码可以全部执行。
       一直到所有的子线程全部运行完毕,主线程才能退出[当前程序]

    3、线程资源独占:强制独占-当前时刻已经启动的线程占用所有资源
        其他线程排队,提升部分线程的优先级,将并发执行变成同步执行
"""
import time
import threading


def test(num):
    """计数器"""
    for i in range(num):
        print(f"{threading.current_thread().getName()}当前的循环次"
              f"数:{i+1};存活线程:{threading.active_count()}")
        time.sleep(1)


if __name__ == "__main__":
    """程序启动的入口"""
    # 创建两个线程
    t1 = threading.Thread(target=test, args=(5,))
    t2 = threading.Thread(target=test, args=(3,))

    # 启动线程
    t1.start()
    t1.join() # ? 位置:t1占用所有资源,线程运行完毕后,其他线程才能执行。
    # t2.join() # 位置:t2线程没有启动,抢占资源就会报错!
    t2.start()
    # t1.join()   # ? 位置:t1线程t2线程,分配所有资源,等待t1线程和t2线程运行完成后,其他线程才能执行
    # t2.join()  # 如果已经由t1.join()在上一行编写了,这里就没有必要写t2.join()

    # 主线程中:会不会等待t1和t2执行完成后,再执行?
    for i in range(2):
        print(f"{threading.current_thread().getName()} i:{i}")
        time.sleep(1)
    print("main线程执行完成......")
  • 运行结果
    在这里插入图片描述

  • 案例二

...
...
...
    # 启动线程
    t1.start()
    t1.join() # ? 位置:t1占用所有资源,线程运行完毕后,其他线程才能执行。
    t2.join() # 位置:t2线程没有启动,抢占资源就会报错!
    t2.start()
    # t1.join()   # ? 位置:t1线程t2线程,分配所有资源,等待t1线程和t2线程运行完成后,其他线程才能执行
    # t2.join()  # 如果已经由t1.join()在上一行编写了,这里就没有必要写t2.join()

...
  • 运行结果
    在这里插入图片描述
  • 案例三
...
...
...
    # 启动线程
    t1.start()
    # t1.join() # ? 位置:t1占用所有资源,线程运行完毕后,其他线程才能执行。
    # t2.join() # 位置:t2线程没有启动,抢占资源就会报错!
    t2.start()
    t1.join()   # ? 位置:t1线程t2线程,分配所有资源,等待t1线程和t2线程运行完成后,其他线程才能执行
    # t2.join()  # 如果已经由t1.join()在上一行编写了,这里就没有必要写t2.join()
...
  • 运行结果
    在这里插入图片描述
  • 案例四
...
...
...
    # 启动线程
    t1.start()
    # t1.join() # ? 位置:t1占用所有资源,线程运行完毕后,其他线程才能执行。
    # t2.join() # 位置:t2线程没有启动,抢占资源就会报错!
    t2.start()
    # t1.join()   # ? 位置:t1线程t2线程,分配所有资源,等待t1线程和t2线程运行完成后,其他线程才能执行
    t2.join()  # 如果已经由t1.join()在上一行编写了,这里就没有必要写t2.join()
...

在这里插入图片描述


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

Python3 threading模块创建线程(一) 的相关文章

  • Lighttpd 和 cgi python

    我正在尝试通过 lighttpd 执行一些 python 脚本 但是当我尝试运行它时 我只得到一个要求我下载的空白文件 lighttpd conf server modules mod access mod alias mod access
  • Python 中的哈希映射

    我想用Python实现HashMap 我想请求用户输入 根据他的输入 我从 HashMap 中检索一些信息 如果用户输入HashMap的某个键 我想检索相应的值 如何在 Python 中实现此功能 HashMap
  • 如何使用 opencv.omnidir 模块对鱼眼图像进行去扭曲

    我正在尝试使用全向模块 http docs opencv org trunk db dd2 namespacecv 1 1omnidir html用于对鱼眼图像进行扭曲处理Python 我正在尝试适应这一点C 教程 http docs op
  • 安装了 32 位的 Python,显示为 64 位

    我需要运行 32 位版本的 Python 我认为这就是我在我的机器上运行的 因为这是我下载的安装程序 当我重新运行安装程序时 它会将当前安装的 Python 版本称为 Python 3 5 32 位 然而当我跑步时platform arch
  • Python getstatusoutput 替换不返回完整输出

    我发现了这个很棒的替代品getstatusoutput Python 2 中的函数在 Unix 和 Windows 上同样有效 不过我觉得这个方法有问题output被构建 它只返回输出的最后一行 但我不明白为什么 任何帮助都是极好的 def
  • 使用 Python 从文本中删除非英语单词

    我正在 python 上进行数据清理练习 我正在清理的文本包含我想删除的意大利语单词 我一直在网上搜索是否可以使用像 nltk 这样的工具包在 Python 上执行此操作 例如给出一些文本 Io andiamo to the beach w
  • 跟踪 pypi 依赖项 - 谁在使用我的包

    无论如何 是否可以通过 pip 或 PyPi 来识别哪些项目 在 Pypi 上发布 可能正在使用我的包 也在 PyPi 上发布 我想确定每个包的用户群以及可能尝试积极与他们互动 预先感谢您的任何答案 即使我想做的事情是不可能的 这实际上是不
  • 使用 kivy textinput 的 'input_type' 属性的问题

    您好 我在使用 kivy 的文本输入小部件的 input type 属性时遇到问题 问题是我制作了两个自定义文本输入 其中一个称为 StrText 其中设置了 input type text 然后是第二个文本输入 名为 NumText 其
  • 使用Python请求登录Google帐户

    在多个登录页面上 需要谷歌登录才能继续 我想用requestspython 中的库以便让我自己登录 通常这很容易使用requests库 但是我无法让它工作 我不确定这是否是由于 Google 做出的一些限制 也许我需要使用他们的 API 或
  • 如何在 Python 中解析和比较 ISO 8601 持续时间? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个 Python v2 库 它允许我解析和比较 ISO 8601 持续时间may处于不同单
  • Python beautifulsoup 仅限 1 级文本

    我看过其他 beautifulsoup 得到相同级别类型的问题 看来我的有点不同 这是网站 我正试图拿到右边那张桌子 请注意表的第一行如何展开为该数据的详细细分 我不想要那个数据 我只想要最顶层的数据 您还可以看到其他行也可以展开 但在本例
  • “隐藏”内置类对象、函数、代码等的名称和性质[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我很好奇模块中存在的类builtins无法直接访问的 例如 type lambda 0 name function of module
  • Docker 中的 Python 日志记录

    我正在 Ubuntu Web 服务器上的 Docker 容器中测试运行 python 脚本 我正在尝试查找由 Python Logger 模块生成的日志文件 下面是我的Python脚本 import time import logging
  • 如何使用 pybrain 黑盒优化训练神经网络来处理监督数据集?

    我玩了一下 pybrain 了解如何生成具有自定义架构的神经网络 并使用反向传播算法将它们训练为监督数据集 然而 我对优化算法以及任务 学习代理和环境的概念感到困惑 例如 我将如何实现一个神经网络 例如 1 以使用 pybrain 遗传算法
  • 不同编程语言中的浮点数学

    我知道浮点数学充其量可能是丑陋的 但我想知道是否有人可以解释以下怪癖 在大多数编程语言中 我测试了 0 4 到 0 2 的加法会产生轻微的错误 而 0 4 0 1 0 1 则不会产生错误 两者计算不平等的原因是什么 在各自的编程语言中可以采
  • 如何解决 PDFBox 没有 unicode 映射错误?

    我有一个现有的 PDF 文件 我想使用 python 脚本将其转换为 Excel 文件 目前正在使用PDFBox 但是存在多个类似以下错误 org apache pdfbox pdmodel font PDType0Font toUnico
  • python import inside函数隐藏现有变量

    我在我正在处理的多子模块项目中遇到了一个奇怪的 UnboundLocalError 分配之前引用的局部变量 问题 并将其精简为这个片段 使用标准库中的日志记录模块 import logging def foo logging info fo
  • 实现 XGboost 自定义目标函数

    我正在尝试使用 XGboost 实现自定义目标函数 在 R 中 但我也使用 python 所以有关 python 的任何反馈也很好 我创建了一个返回梯度和粗麻布的函数 它工作正常 但是当我尝试运行 xgb train 时它不起作用 然后 我
  • Scipy Sparse:SciPy/NumPy 更新后出现奇异矩阵警告

    我的问题是由大型电阻器系统的节点分析产生的 我基本上是在设置一个大的稀疏矩阵A 我的解向量b 我正在尝试求解线性方程A x b 为了做到这一点 我正在使用scipy sparse linalg spsolve method 直到最近 一切都
  • cv2.VideoWriter:请求一个元组作为 Size 参数,然后拒绝它

    我正在使用 OpenCV 4 0 和 Python 3 7 创建延时视频 构造 VideoWriter 对象时 文档表示 Size 参数应该是一个元组 当我给它一个元组时 它拒绝它 当我尝试用其他东西替换它时 它不会接受它 因为它说参数不是

随机推荐