在Python中使用多线程(通俗版本)

一、多线程的介绍:

1.进程

通常一个进程包含一个或者多个线程,每个进程有自己独立的一块内存空间,所有的线程共享这一块空间,例如:在Windows操作系统中,一个运行的xx.exe就是一个进程。

2.线程

一个进程总得有多个执行任务吧,例如我有一个学生信息查询进程,当我想要查询某个学生信息时,它大致包含以下几个任务

1.进程接收学生信息并发送给服务器

2.进程接收学生信息

3.进程分析学生信息

4.进程将学生信息展示出来

不难理解,如果一个进程只有一个线程,那么这个线程将会按照顺序执行四个任务,那么总耗费时间就是t1+t2+t3+t4的时间。

但是如果我们使用多线程,我们拥有三个线程,那么我们就可以边接收学生信息(任务二),边分析学生信息(任务三),边展示学生信息(任务四)

那么总时间将无限接近于t1+t2

可以看到,这大大提升了工作效率,除此之外,线程还拥有更小的系统开销代价,相较于多进程来说,多线程的开销远远小于多进程,并且由于线程间数据可以共享,为此在处理“密集型I/O型任务”时,我们可以使用多线程来提升工作效率。

密集型I/O型任务举例爬虫中大量获取接口、GUI页面的子页面。

二、多线程的使用

0.多线程的使用方式:

在Python中实现多线程的库有很多,在这里我们使用最常见的“threading”库。

1.显示线程信息的属性的方法:

import threading

if __name__ == "__main__":
    print("当前进程数量为:",threading.active_count())
    print("当前所有的线程为:",threading.enumerate())    #以列表的形式显示
    print("当前线程为:",threading.current_thread())

效果图:

2.添加线程

在threading中添加线程,使用内置的“Thread”类,先创建Thread对象,再使用start()方法启动这个线程。
threading.Thread(target=Nonename=Noneargs=()kwargs={}*daemon=None)

其中:

1.target为函数名,或者可调用对象

2.name是线程名称,如果不指定系统会随机生成。

3.args用于发起调用目标函数的参数列表元组默认是()

4.kwargs是用于发起调用目标函数的关键字参数字典,默认是{}

5.daemon(3.3版本新增),daemon如果不是默认值None,则该线程为守护线程。

import threading
import time

def job1():
    #让这个线程暂停5秒,便于区分
    time.sleep(1)
    print("job1成功执行啦,执行该函数的线程是:",threading.current_thread())

if __name__ == "__main__":
    #创建一个线程,并且不给该线程使用name参数指定名字
    my_thread_1 = threading.Thread(target=job1)
    #创建一个线程,并且给该线程使用name参数指定名字
    my_thread_2 = threading.Thread(target=job1,name="t1")
    #启动两个线程
    my_thread_2.start()
    my_thread_1.start()
    print("当前进程数量为:",threading.active_count())
    print("当前所有的线程为:",threading.enumerate())    #以列表的形式显示
    print("当前线程为:",threading.current_thread())

效果图:

可以看到,线程1和线程2是同时完成的,因为两条打印语句都“挤到一起”了。

3.线程间的堵塞

3.1为什么要使用堵塞

我们继续看上面提到的学生查询例子,在任务四中,进程需要展示学生信息,但如果任务四的执行速度大于任务三大于任务二,会出现什么状况呢?

此时,学生的全部信息尚未接收完全,但是任务四的线程已经执行完毕了,这就导致最后展示出来的学生信息是不全的,这显然不是我们想要的结果,那我们该怎么办呢?

这就不得不搬出线程的“堵塞”了。

3.2堵塞的作用

线程堵塞顾名思义,会将某个线程堵住,从而使这个线程卡住,直到解除线程堵塞。

为此我们可以适当的将任务四的线程堵塞,直到任务二任务三的线程执行的差不多了,我们再解除任务四的堵塞即可

3.3使用join()函数来完成线程堵塞的操作

join()函数的使用方法:

A函数中使用join()函数,那么A函数会卡住,直到被使用join()函数的线程执行完毕,函数A才会继续进行

import threading
import time

def B():
    #让这个线程暂停1秒,便于区分
    time.sleep(1)
    print(f"嗨,我是B函数~我被线程{threading.current_thread()}使用.")

def A():
    #创建B线程,注意的是A本身就是一个线程A
    new_threading = threading.Thread(target=B)
    #启动B线程
    new_threading.start()
    #堵塞A线程,使用线程B堵塞A线程。
    new_threading.join()
    print(f"嗨,我是A函数~我被线程{threading.current_thread()}使用.")
    print("当前进程数量为:",threading.active_count())
    print("所有的线程为:",threading.enumerate())    #以列表的形式显示

if __name__ == "__main__":
    A()

效果图:

可以看到,线程B在执行完B函数之后,自动销毁了,此时线程数量仅为1了。

3.4线程执行的结果使用Queue来存储

虽然线程之间共享数据,但是在Threading库中,除主线程外,子线程执行的结果并不能通过return来返回数据,为此我们需要使用“Queue”来存储。

可以理解为,子线程虽然无法返回数据,但是子线程之间可以用Queue队列管道来存储结果

为此,我们需要安装queue库

import threading
from queue import Queue

def job(l, q):
    for i in range(len(l)):
        l[i] = l[i] * 10
    #使用put方法向队列中添加数据
    q.put(l)


def tasks():
    # 创建队列
    q = Queue()
    # 线程列表
    threads = []
    # 二维列表
    data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    for i in range(3):
        t = threading.Thread(target=job, args=(data[i], q))
        t.start()
        threads.append(t)

    # 对所有线程进行阻塞
    for thread in threads:
        thread.join()
    results = []
    # 将新队列中的每个元素挨个放到结果列表中
    for _ in range(3):
        #使用get方法在队列中取数据.
        #当对列为空时,线程会卡在这里,一直在请求获取数据,直到获取到数据为止.
        #可以使用q.empty()方法判断队列是否为空.
        results.append(q.get())
    print(results)


if __name__ == "__main__":
    tasks()

效果图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/427085.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

低代码流程引擎实战:让表单字段成为流程节点审批人的得力助手!

在现代企业的日常运营中,流程审批是保障工作高效、规范进行的关键环节。随着企业对于灵活性和高效性的需求不断增长,传统的固定审批人设置已无法满足多变的业务场景。在JVS低代码中“设置流程节点审批人为表单字段”这一功能,旨在通过动态配置…

leetcode第 387 场周赛总结

很久没打周赛了,这周开始恢复 这次周赛,题目比较简单,第三道题有点浪费了时间,思路是对的,但是被我把问题复杂化了。 给你一个下标从 1 开始、包含 不同 整数的数组 nums ,数组长度为 n 。 你需要通过 n 次…

大模型总结

抛开大模型基座训练,我们还可以关注什么? - 知乎 大模型LLM领域,有哪些可以作为学术研究方向? 方向一:大模型的基础理论问题 大力出奇迹,涌现,目前还需要科学家继续研究理论基础 也就是先有…

曲线生成 | 图解Dubins曲线生成原理(附ROS C++/Python/Matlab仿真)

目录 0 专栏介绍1 什么是Dubins曲线?2 Dubins曲线原理2.1 坐标变换2.2 单步运动公式2.3 曲线模式 3 Dubins曲线生成算法4 仿真实现4.1 ROS C实现4.2 Python实现4.3 Matlab实现 0 专栏介绍 🔥附C/Python/Matlab全套代码🔥课程设计、毕业设计、…

Windows10 安装Neo4j流程

1、下载并安装ava运行环境 官网链接(需要注册Oracle账号):https://www.oracle.com/java/technologies/downloads/ 根据自己Neo4j版本确认需要的JDK版本 百度网盘链接: 链接:链接:https://pan.baidu.com/s/…

怎么倒放视频?3个倒放方法分享给你

怎么倒放视频?倒放视频不仅有趣且充满创意,而且还能创造出一种令人惊叹的视觉效果,将观众带入一个全新的时空维度。通过将动作和事件倒放,我们可以观察到平时难以察觉的细节,理解事物运行的逆向逻辑。这种独特的编辑手…

Pycharm无法粘贴外部文本问题

Pycharm无法粘贴外部文本问题 百度找了好多是因为安装了vim,最后发现是因为pycharm粘贴框存在了很多内容导致 操作方法: 1、清理所有缓存的复制内容 ctrlshiftV 可以看到编译器所有缓存下来的复制文本 2、ctrlA然后delete 解决:此时再复…

最短路径(2.19)

目录 1.网络延迟时间 弗洛伊德算法 迪杰斯特拉算法 2. K 站中转内最便宜的航班 3.从第一个节点出发到最后一个节点的受限路径数 4.到达目的地的方案数 1.网络延迟时间 有 n 个网络节点,标记为 1 到 n。 给你一个列表 times,表示信号经过 有向 边的…

数据结构与算法----复习Part 12 (字符串初步)

本系列是算法通关手册LeeCode的学习笔记 算法通关手册(LeetCode) | 算法通关手册(LeetCode) (itcharge.cn) 目录 一,字符串(String) 二,字符串的比较 三,字符串的存储…

AI算法的调优流程

AI算法的调优是提高模型性能和效率的关键步骤之一。以上流程是一个通用的AI算法调优流程,具体应用时可能需要根据问题类型、数据特征和业务需求进行调整和扩展。北京木奇移动技术有限公司,专业的软件外包开发公司,欢迎交流合作。 1. 确定性能…

回归预测 | Matlab实现RIME-BP霜冰算法优化BP神经网络多变量回归预测

回归预测 | Matlab实现RIME-BP霜冰算法优化BP神经网络多变量回归预测 目录 回归预测 | Matlab实现RIME-BP霜冰算法优化BP神经网络多变量回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab实现RIME-BP霜冰算法优化BP神经网络多变量回归预测(完整…

2024第二届化学工程、材料与能源科学国际会议(ICCEMES2024)

2024第二届化学工程、材料与能源科学国际会议(ICCEMES2024) 一、【会议简介】 2024第二届化学工程、材料与能源科学国际会议(ICCEMES2024)将于2024年在美丽的三亚市举行。本次会议旨在汇聚全球化学工程、材料与能源科学领域的专家学者,共同探讨和交流相关领域的最…

第二篇【传奇开心果系列】Python的自动化办公库技术点案例示例:深度解读Pandas金融数据分析

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas 在金融数据分析中的常见用途和功能介绍二、金融数据清洗和准备示例代码三、金融数据索引和选择示例代码四、金融数据时间序列分析示例代码五、金融数据可视化示例代码六、金融数…

易语言源代码5000例

仅供学习研究交流使用 加群下载

MySQL8安装切换密码验证方式

一、MySQL8中新增了一种密码验证方式:caching_sha2_password,如果安装时选择了如下方式: 则数据库使用新的caching_sha2_password密码验证方式。 二、如果安装时选择了caching_sha2_password验证方式,而安装后想发回传统的mysql_…

医学大数据|统计基础|医学统计学(笔记):开学说明与目录

开始学习统计基础,参考教材:医学统计学第五版 点点关注一切来学习吧 责任编辑:医学大数据刘刘老师:头部医疗大数据公司医学科学部研究员 邮箱:897282268qq.com 久菜盒子工作室 我们是:985硕博/美国全奖…

【EI会议征稿通知】第四届能源工程、新能源材料与器件国际学术会议(NEMD 2024)

第四届能源工程、新能源材料与器件国际学术会议(NEMD 2024) 2024 4th International Academic Conference on Energy Engineering, new energy materials and devices 第四届能源工程、新能源材料与器件国际学术会议(NEMD 2024&#xff09…

免费在线Axure终于找到了,赶紧试试!

Axure作为一种功能强大的原型设计工具,一直受到设计师的青睐。然而,其高昂的价格可能成为一个门槛,限制了一些设计师的选择。但别担心,现在有一个免费的Axure在线工具即时设计,功能更齐全,性价比更高&#…

用BIO实现tomcat

一、前言 本课程的难度较高,需要将Servlet原理和IO课程全部学完。 二、当前项目使用方式 (1).自定义servlet 自定义servlet需要实现WebServlet并且实现name和urlMapping 重启进行访问 http://localhost:8090/myServlet (2).自定义html 重启进行访问 http://loc…

幂等性设计

目录 前言 幂等性设计 幂等性设计处理流程 HTTP 幂等性 消息队列幂等性 基于kafka 前言 幂等性设计,就是说,一次和多次请求某一个资源应该具有同样的副作用。为什么我们要有幂等性操作?说白了,就两点:1、网络的…