首页 > 编程语言 >python多线程

python多线程

时间:2024-04-26 10:26:22浏览次数:28  
标签:thread python image 任务 线程 time 多线程

  • 多线程的原理是在同一进程内创建多个线程来执行不同的任务,这些线程共享同一进程的资源,包括内存空间、文件句柄等。每个线程拥有独立的执行路径,可以并行执行任务,从而提高程序的效率。
  • 在代码中,通过调用 threading.Thread 类创建了多个线程对象。每个线程对象都有一个 target 参数,指定了该线程要执行的函数,以及一个 args 参数,传入了该函数所需的参数。在调用 thread.start() 方法后,系统会为该线程分配资源,并执行指定的函数。
  • 由于操作系统会分配给每个线程一定的时间片来执行任务,因此多个线程可以在同一时刻并发执行不同的任务。这样,在处理大量图片文件时,可以同时加载、处理和保存多张图片,从而提高了整体的处理效率。

单线程和多线程对比

import threading
import time

# 假设这是一批大型图片文件列表
image_files = ["image1.jpg", "image2.jpg", "image3.jpg", "image4.jpg", "image5.jpg"]

# 定义一个函数,用于处理图片的整个流程(加载、处理、保存)
def process_image_workflow(image_file):
    # 这里用 sleep 来模拟 加载、处理、保存 时间 
     time.sleep(6)

# 定义一个函数,用于单线程处理图片
def process_images_single_threaded(image_files):
    start_time = time.time()
    for image_file in image_files:
        process_image_workflow(image_file)
    end_time = time.time()
    print(f"单线程处理图片总耗时:{end_time - start_time} 秒")             # 30.148472547531128 秒

# 定义一个函数,用于创建并启动线程来处理图片
def process_images_threaded(image_files):
    start_time = time.time()
    threads = []  # 用于存储线程对象
    for image_file in image_files:
        thread = threading.Thread(target=process_image_workflow, args=(image_file,))
        threads.append(thread)
        thread.start()   # 启动线程,使其开始执行 process_image_workflow 函数中定义的任务

    # 等待所有线程执行完成
    for thread in threads:
        thread.join()
    end_time = time.time()
    print(f"多线程处理图片总耗时:{end_time - start_time} 秒")             # 6.02411675453186 秒

if __name__ == "__main__":
    print("单线程处理图片:")
    process_images_single_threaded(image_files)   
    print("\n多线程处理图片:")
    process_images_threaded(image_files)

image-20240406213401686

image-20240406213431224

如何确定几个线程

确定使用多少个线程来处理任务通常是一个复杂的问题,需要考虑多个因素,包括但不限于以下几点:

  1. 任务的性质和工作负载:不同类型的任务可能对线程数量的需求不同。有些任务可能是 CPU 密集型的,需要更多的线程来充分利用 CPU 的计算资源;而有些任务可能是 I/O 密集型的,需要更多的线程来充分利用 I/O 操作的并行性。
  2. 系统资源:系统的硬件资源限制了可以同时运行的线程数量。例如,CPU 的核心数、内存大小等都会影响线程的数量选择。
  3. 线程间的竞争和同步:过多的线程可能导致线程间频繁地竞争资源,造成性能下降。同时,线程间的同步也会增加复杂性和开销。因此,需要权衡线程数量和同步机制的选择。
  4. 任务的分解和并行度:如果任务可以很容易地分解成多个独立的子任务,并且这些子任务可以并行执行,那么就可以考虑增加线程数量来提高并行度,从而加快整体处理速度。
  5. 实验和性能测试:最终确定线程数量通常需要通过实验和性能测试来确定。可以尝试不同数量的线程,并测量处理任务所需的时间,以找到最佳的线程数量。

总的来说,确定线程数量需要综合考虑任务本身的性质、系统资源限制、线程间的竞争和同步等因素,并通过实验和性能测试来确定最佳的线程数量。

如果图片数量增加到一百张,那么就会创建一百个线程来处理这些图片。这种方法在图片数量较少时可能是可行的,但在大规模处理时可能会遇到一些问题:

  1. 资源消耗:创建大量线程会消耗系统资源,包括内存和CPU时间片。如果线程数量过多,可能会导致系统性能下降。
  2. 竞争和同步:过多的线程可能会导致线程间频繁竞争资源,例如CPU和内存。同时,线程间的同步也可能增加复杂性和开销。
  3. 性能稳定性:大量线程的创建和管理可能会导致性能不稳定,例如线程间的切换开销和调度延迟等问题。

针对大规模图片处理,你可以考虑以下优化策略:

  1. 线程池:使用线程池来管理线程的创建和销毁,避免频繁创建和销毁线程带来的开销。
  2. 任务分批:将大量图片分批处理,每批处理一定数量的图片,然后使用线程池来处理每一批图片。
  3. 异步处理:使用异步编程模型,例如使用asyncio库来实现异步IO操作,提高程序的并发性能。
  4. 资源限制:根据系统资源情况和性能测试结果,设定合理的线程数量上限,避免过多线程导致的资源竞争和性能下降。

综上所述,针对大规模图片处理,合理地管理线程数量和资源是非常重要的,需要根据实际情况进行优化和调整。

根据以下准则来设置多线程的数量:

IO密集型任务:一般情况下,线程数应该大于CPU核心数,以充分利用CPU等待IO操作的时间。可以根据经验选择一个适当的倍数,例如2倍或4倍。

计算密集型任务:由于Python的GIL(Global Interpreter Lock)限制了多线程中的并行计算,所以多线程并不适合用于加速计算密集型任务。在这种情况下,使用多进程或协程可能更合适。

以下是设置线程数量的示例代码:

import threading

# 获取CPU核心数
cpu_count = threading.cpu_count()

# 设置线程数量
thread_count = cpu_count * 2  # 可根据实际情况进行调整

运行程序:

import threading

# 创建并启动线程
def run_task():
    # TODO: 编写具体的任务逻辑
    pass

threads = []
for _ in range(thread_count):
    thread = threading.Thread(target=run_task)
    thread.start()
    threads.append(thread)

# 等待所有线程执行完毕
for thread in threads:
    thread.join()

标签:thread,python,image,任务,线程,time,多线程
From: https://www.cnblogs.com/DQ-MINE/p/18159387

相关文章

  • 用python写一段将指定文件夹下的子文件夹下的“.en.srt”文件复制一份,并将复制的文件
    代码:importosimportshutildefcopy_and_rename_en_srt_files(parent_directory):#遍历指定的父目录及其所有子目录forroot,dirs,filesinos.walk(parent_directory):forfileinfiles:#检查文件是否以.en.srt结尾if......
  • KNN算法思想与Python实现
    古语说得好,物以类聚,人以群分;近朱者赤,近墨者黑。这两句话的大概意思就是,你周围大部分朋友是什么人,那么你大概率也就是这种人,这句话其实也就是K最近邻算法的核心思想。kNN(k-NearestNeighbor)法即k最邻近法,最初由Cover和Hart于1968年提出,是一个理论上比较成熟的方法,也是最简单的机......
  • Socket.D v2.4.12 发布(新增 python 实现)
    Socket.D协议?Socket.D是一个网络应用协议。在微服务、移动应用、物联网等场景,可替代http、websocket等。协议详情参考《官网介绍》。支持:tcp,udp,ws,kcp传输。目前:java,kotlin,javascript,node.js,python语言环境可用。go,rust,c/c++,.net正在开发中。forJava更新......
  • blender python api 使用脚本进行动画渲染
    1.摄像机“Camera”在一个名叫“渲染”的集合中2.代码:importbpy#设置输出路径和文件名output_path="/path/to/output/"#替换为你的输出路径filename="rendered_animation"#输出文件的前缀#获取名为“渲染”的集合render_collection_name="渲染"render_c......
  • 【python】pyqt中使用多线程处理耗时任务
    在PyQt中使用多线程通常是为了避免界面冻结,特别是在执行耗时的任务时。PyQt本身是基于Qt的,而Qt不允许在除主线程之外的线程中直接操作GUI元素。因此,任何涉及GUI更新的操作都应该在主线程中执行。importsysimportthreadingfromPyQt5.QtWidgetsimportQApplic......
  • Python 字符串格式化指南
    前言在Python中,字符串格式化是一种常见且重要的操作,用于将变量或值插入到字符串中,并控制输出的格式。本文将介绍几种常见的字符串格式化方法,帮助大家掌握在Python中有效地处理字符串的技巧。方法一:使用%操作符格式化字符串使用%操作符是一种传统的字符串格式化方法,可......
  • 深入理解多线程编程
    title:深入理解多线程编程date:2024/4/2517:32:02updated:2024/4/2517:32:02categories:后端开发tags:线程同步互斥锁死锁避免竞态条件线程池异步编程性能优化第一章:多线程基础1.1线程概念与原理线程:在操作系统中,一个程序可以被划分为多个执行流,每个......
  • Qt 中多线程对应的信号槽
    Qt中通过moveToThread方式来实现的多线程之间数据交互一般是通过信号槽来进行的,信号槽不仅可以用于同一个线程中,也可以用于多线程之间,当用于多线程之间时,其连接方式为Qt::QueuedConnection,即队列连接。多线程之间建立的信号槽主要为如下两个:主线程发送信号:来触发子线程的......
  • Python GUI开发- Qt Designer环境搭建
    前言QtDesigner是PyQt5程序UI界面的实现工具,使用QtDesigner可以拖拽、点击完成GUI界面设计,并且设计完成的.ui程序可以转换成.py文件供python程序调用环境准备使用pip安装pipinstallpyqt5-toolsQtDesigner环境搭建在pip安装包的路径中,找到designer.exe文件......
  • Python3.8.4 解决 ImportError: urllib3 v2 only supports OpenSSL 1.1.1+, currently
    系统版本:CentOSLinuxrelease7.6.1810(Core)编译安装Python3.8.4[root@hankyoon~]#tar-xvfPython-3.8.4.tgz[root@hankyoon~]#cdPython-3.8.4/[root@hankyoon~]#./configure--prefix=/usr/local/python3.8[root@hankyoon~]#make&&makeinstall[......