(python)多线程

前言

        Python 多线程的应用场景通常是在需要同时执行多个 I/O 密集型任务时,以提高程序的效率和性能。

多线程应用场景

  1. 网络爬虫:当需要从多个网站获取数据时,使用多线程可以同时发起多个 HTTP 请求,以加快数据获取速度。

  2. 数据库操作:当需要对大量数据进行读取、写入或修改时,使用多线程可以将任务分成多个子任务,每个子任务在不同的线程中执行,以提高数据库操作效率。

  3. 图像处理:当需要对大量图像进行处理时,使用多线程可以将处理任务分成多个子任务,每个子任务在不同的线程中处理,以提高图像处理速度。

  4. 并发服务器:当需要同时处理多个客户端请求时,使用多线程可以让服务器同时处理多个请求,以提高服务器的吞吐量。

优点

  1. 提高程序的响应速度:在执行多个 I/O 密集型任务时,多线程可以并行执行这些任务,从而提高程序的响应速度。

  2. 简化编程模型:使用多线程可以将复杂的任务分解成多个子任务,并使用多个线程同时执行这些子任务,使得程序结构更清晰。

  3. 资源共享:多线程可以共享同一进程的资源,包括内存空间、文件描述符等,方便数据共享和通信。

  4. 适用于 I/O 密集型任务:适合处理需要大量等待 I/O 操作的任务,如网络请求、文件读写等。

缺点

  1. 全局解释器锁(GIL):Python 的全局解释器锁会导致多线程无法利用多核 CPU,限制了多线程的并行性能。

  2. 线程安全性:多线程编程需要考虑线程安全性问题,如数据竞争、死锁等,增加了程序设计和调试的难度。

  3. 可扩展性受限:由于 GIL 的存在,多线程并不能实现真正的并行执行,因此在 CPU 密集型任务上性能提升有限。

  4. 调试困难:多线程程序更容易出现并发相关的 bug,调试和定位问题相对困难

绕不开的瓶颈-全局解释器锁(GIL)

        全局解释器锁(Global Interpreter Lock,简称 GIL)是 Python 解释器中的一个机制,用于保护共享资源,即 Python 对象的内存管理。在 CPython 解释器中(即官方的 Python 解释器实现),GIL 的存在限制了同一时刻只有一个线程可以执行 Python 字节码。

  1. 线程安全性:由于 Python 的内存管理机制并不是线程安全的,多个线程同时操作 Python 对象可能会导致数据结构损坏或内存泄漏。因此,GIL 通过限制同一时刻只有一个线程执行 Python 字节码,保证了 Python 对象的线程安全。

  2. 简化实现:GIL 简化了 CPython 解释器的实现,减少了对内存管理的复杂度,降低了解释器的开发和维护成本。

 限制和缺点

  1. 性能影响:在 CPU 密集型任务中,GIL 会限制多线程的并发执行,因为同一时刻只有一个线程能够执行 Python 字节码,导致无法充分利用多核 CPU。

  2. 阻碍并行性:由于 GIL 的存在,Python 多线程并不能实现真正的并行执行,只能依靠多进程来充分利用多核 CPU。

  3. 影响扩展性:对于需要高性能并发的应用,如 Web 服务器、科学计算等,GIL 可能成为性能瓶颈,限制了应用的扩展性。

 使用范例

采用多线程

import datetime
import threading
import time


# 定义一个简单的函数,用于在多线程中执行
def task():
    thread_name = 1
    print(f"Thread {thread_name} is starting")

    print(f"Thread {thread_name} is start IO")
    time.sleep(3)  # 模拟耗时操作
    print(f"Thread {thread_name} is finish IO")

    print(f"Thread {thread_name} is start 计算")
    time.sleep(1)  # 模拟耗时操作
    print(f"Thread {thread_name} is finish 计算")

    print(f"Thread {thread_name} is start 输出")
    time.sleep(1)  # 模拟耗时操作
    print(f"Thread {thread_name} is finish 输出")

    print(f"Thread {thread_name} is finishing")


def task2():
    thread_name = 2
    print(f"Thread {thread_name} is starting")

    print(f"Thread {thread_name} is start IO")
    time.sleep(1)  # 模拟耗时操作
    print(f"Thread {thread_name} is finish IO")

    print(f"Thread {thread_name} is start 计算")
    time.sleep(1)  # 模拟耗时操作
    print(f"Thread {thread_name} is finish 计算")

    print(f"Thread {thread_name} is start 输出")
    time.sleep(1)  # 模拟耗时操作
    print(f"Thread {thread_name} is finish 输出")

    print(f"Thread {thread_name} is finishing")


def run():
    task()

    task2()


t1 = datetime.datetime.now()
# 创建多个线程
thread1 = threading.Thread(target=task)
thread2 = threading.Thread(target=task2)

threads = [thread1, thread2]

# 启动并等待所有线程执行完成
for thread in threads:
    thread.start()

for thread in threads:
    thread.join()

cost_time = (datetime.datetime.now() - t1).seconds
print(f"All threads have finished cost_time={cost_time}s")

"""
Thread 1 is starting
Thread 1 is start IO
Thread 2 is starting
Thread 2 is start IO
Thread 2 is finish IO
Thread 2 is start 计算
Thread 2 is finish 计算
Thread 2 is start 输出
Thread 2 is finish 输出Thread 1 is finish IO
Thread 1 is start 计算

Thread 2 is finishing
Thread 1 is finish 计算
Thread 1 is start 输出
Thread 1 is finish 输出
Thread 1 is finishing
All threads have finished cost_time=5s
"""

不采用多线程

# 按顺序运行两个任务
run()

cost_time = (datetime.datetime.now() - t1).seconds
print(f"All threads have finished cost_time={cost_time}s")

"""
Thread 1 is starting
Thread 1 is start IO
Thread 1 is finish IO
Thread 1 is start 计算
Thread 1 is finish 计算
Thread 1 is start 输出
Thread 1 is finish 输出
Thread 1 is finishing
Thread 2 is starting
Thread 2 is start IO
Thread 2 is finish IO
Thread 2 is start 计算
Thread 2 is finish 计算
Thread 2 is start 输出
Thread 2 is finish 输出
Thread 2 is finishing
All threads have finished cost_time=8s
"""

采用多线程的前后对比

 注意:在使用多线程的测试样例中,CPU的资源只有一个,只要不同时使用就不会产生额外的等待时间.否则,需要用线程锁来控制它们对共同资源的使用权.

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

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

相关文章

新闻稿软文投放推广发布需要注意什么

在全球化的背景下,各国之间的联系与互动变得越来越频繁。无论是经济、文化还是科技领域,各国之间的交流和合作都在不断加深。而在这个信息爆炸的互联网时代,人们获取信息的主要途径也逐渐转向了网络。 在这种情况下,软文推广成为…

Python+neo4j构建豆瓣电影知识图谱

文章目录 数据来源数据整理导入节点和关系导入使用Subgraph批量导入节点和关系 多标签实体和实体去重 数据来源 http://www.openkg.cn/dataset/douban-movie-kg 该网址拥有丰富的中文知识图谱数据集,OpenKG(Open Knowledge Graph),可供研究人员使用研究…

数据库-第二/三章 关系数据库和标准语言SQL【期末复习|考研复习】

前言 总结整理不易,希望大家点赞收藏。 给大家整理了一下计数据库系统概论中的重点概念,以供大家期末复习和考研复习的时候使用。 参考资料是王珊老师和萨师煊老师的数据库系统概论(第五版)。 文章目录 前言第二、三章 关系数据库和标准语言SQL2.1 关系2…

如何使用Portainer创建Nginx容器并搭建web网站发布至公网可访问【内网穿透】

文章目录 前言1. 安装Portainer1.1 访问Portainer Web界面 2. 使用Portainer创建Nginx容器3. 将Web静态站点实现公网访问4. 配置Web站点公网访问地址4.1公网访问Web站点 5. 固定Web静态站点公网地址6. 固定公网地址访问Web静态站点 前言 Portainer是一个开源的Docker轻量级可视…

STM32自学☞AD单通道

程序的最终运行成果: 当转动电位器时,数值和电压值发生变化 ad.c文件 #include "stm32f10x.h" #include "stm32f10x_adc.h" #include "ad.h" #include "stdint.h" void ad_Init(void) { /* 初始化步骤:…

Python爬虫——Urllib库-中

编解码 问题引入 例如: https://www.baidu.com/s?wd章若楠 https://www.baidu.com/s?wd%E7%AB%A0%E8%8B%A5%E6%A5%A0 第二部分的一串乱码就是章若楠 如果这里是写的章若楠就会 产生这样的错误 所以我们就可以使用get请求方式的quote方法了 get请求方式的q…

thefour--Love is like a tide

最后一部分了,要开始进行我们的训练了。 先上代码: import os import numpy as np from tqdm import tqdm import tensorflow as tf from thetwo import NeuralStyleTransferModel import theone import thethree #创建模型 modelNeuralStyleTransferM…

从零开始写 Docker(三)---基于 cgroups 实现资源限制

本文为从零开始写 Docker 系列第三篇,在mydocker run 基础上基于 cgroups 实现容器的资源限制。 完整代码见:https://github.com/lixd/mydocker 欢迎 Star 如果你对云原生技术充满好奇,想要深入了解更多相关的文章和资讯,欢迎关注…

C# Post数据或文件到指定的服务器进行接收

目录 应用场景 实现原理 实现代码 PostAnyWhere类 ashx文件部署 小结 应用场景 不同的接口服务器处理不同的应用,我们会在实际应用中将A服务器的数据提交给B服务器进行数据接收并处理业务。 比如我们想要处理一个OFFICE文件,由用户上传到A服务器…

紫罗兰栽培养护简单,这些要点多注意——花园传说

紫罗兰,以其独特的芬芳和优雅的花姿,历来备受人们的喜爱。无论是摆放在室内还是庭院中,紫罗兰都能为生活增添一份别样的雅致。那么,如何将紫罗兰成功栽培到家中呢?下面就为大家详细介绍紫罗兰的养殖方法及养护要点。 选…

《Spring Security 简易速速上手小册》第3章 用户认证机制(2024 最新版)

文章目录 3.1 认证流程3.1.1 基础知识详解认证流程的核心概念认证流程的步骤 3.1.2 主要案例:内存用户认证案例 Demo:快速启动你的 Spring Boot 守护程序 3.1.3 拓展案例 1:数据库用户认证案例 Demo:让数据库守护你的秘密 3.1.4 拓…

Django学习笔记-ModelForm使用(完全依赖)

1.创建模型 ,code,name,sex,entrydate 2.模型映射 python manage.py makemigrations myapp01,python manage.py migrate 3.创建模型表单,继承forms.ModelForm,Meta:元数据,models需引入,fields填写引用的模型变量 4.创建testModelForm.html,添加urls 5.views编写testmodelfo…

【Python笔记-设计模式】模板方法模式

一、说明 模板方法模式是一种行为设计模式,就是继承和多态的使用,将通用操作在父类中实现,不同操作的细节在子类中具体实现,父类只声明接口。 (一) 解决问题 减少相似逻辑的重复代码,提高代码复用性提高代码逻辑性&…

深入探讨Python中的os模块:基础大总结与实战【第109篇—os模块】

深入探讨Python中的os模块:基础大总结与实战 在Python编程中,操作系统(os)模块是一个强大的工具,它提供了与操作系统交互的各种功能,使得开发者能够轻松地执行文件和目录操作、获取系统信息以及执行系统命令。在本篇技术博客中&a…

React中对表格实现列表的拖拽排序

1. 效果:推拽手柄列 2. 实现: react中我们需要两个包来实现 ‘array-move’‘react-sortable-hoc’Installation Use npm $ npm install react-sortable-hoc --save 引入 import { arrayMoveImmutable } from array-move import { SortableContainer, SortableElement, Sort…

具身智能计算系统,机器人时代的 Android | 新程序员

【导读】具身智能作为一种新兴的研究视角和方法论,正在刷新我们对智能本质及其发展的理解:传统的 AI 模型往往将智能视为一种独立于实体存在的抽象能力,而具身智能则主张智能是实体与其环境持续互动的结果。 本文深度剖析了具身智能计算系统…

Unity(第十六部)声音和视频

声音 1、听声音 创建相机的时候,相机自带Audio Listener 多个相机的时候,我们只保留一个Audio Listener就可以 2、声音源,环境音 添加Audio Source就行中文叫声音源 3、脚本执行的声音 using System.Collections; using System.Collection…

如何用ai智能写作?推荐5款优秀的AI写作神器

写作是件繁琐的事情,也是需要耗费精力和时间的,还好目前有了ai写作神器的出现,帮助我们解决了不少的写作难题。这些AI写作工具不仅可以帮助我们提高写作效率,还能够生成高质量的内容。在本文中,我将向你推荐5款优秀的A…

CentOS 定时调度

文章目录 一、场景说明二、脚本职责三、参数说明四、操作示例五、注意事项 一、场景说明 本自动化脚本旨在为提高研发、测试、运维快速部署应用环境而编写。 脚本遵循拿来即用的原则快速完成 CentOS 系统各应用环境部署工作。 统一研发、测试、生产环境的部署模式、部署结构、…

深度学习 精选笔记(7)前向传播、反向传播和计算图

学习参考: 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增),以达到集多方教程的精华于一文的目的。 ③非常推荐上面(学习参考&#x…
最新文章