Python多线程和多进程深度解析

Python中多进程与多线程技术解析 (2) 进程池优化 (3) 进程间通信 队列(Queue):线程安全的FIFO数据结构 管道(Pipe):双向通信通道 共享内存(Value/Array):通过实现 2. 多线程编程实践 (1) 线程创建 (2) 同步机制 三、性能瓶颈与解决方案 1. GIL机制深度解析 Python的全局解释器锁(GIL)导致同一时刻仅有一个线程执行字节码,这使得:通过合理选择多进程与多线程技术,开发者可显著提升Python程序的执行效率。建议在实际项目中结合高阶API进行抽象,并通过性能分析工具(如 阅读详情

Python多线程和多进程深度解析

作为一名从后端开发转向Rust的开发者,我发现Python的多线程和多进程与Rust的并发模型有很多相似之处,但也有一些不同。Python的多线程和多进程可以用于并发执行任务,提高程序的性能。今天我想分享一下我对Python多线程和多进程的理解和实践。

多线程的基本概念

线程是进程内的一个执行单元,多个线程可以共享进程的资源。Python的多线程通过threading模块实现。

import threading
import time

def worker():
    print(f"Worker thread {threading.current_thread().name} started")
    time.sleep(1)
    print(f"Worker thread {threading.current_thread().name} completed")

# 创建线程
threads = []
for i in range(5):
    t = threading.Thread(target=worker, name=f"Thread-{i}")
    threads.append(t)
    t.start()

# 等待所有线程完成
for t in threads:
    t.join()

print("All threads completed")

多进程的基本概念

进程是操作系统分配资源的基本单位,每个进程有自己的内存空间。Python的多进程通过multiprocessing模块实现。

import multiprocessing
import time

def worker():
    print(f"Worker process {multiprocessing.current_process().name} started")
    time.sleep(1)
    print(f"Worker process {multiprocessing.current_process().name} completed")

# 创建进程
processes = []
for i in range(5):
    p = multiprocessing.Process(target=worker, name=f"Process-{i}")
    processes.append(p)
    p.start()

# 等待所有进程完成
for p in processes:
    p.join()

print("All processes completed")

线程安全

由于多个线程共享进程的资源,需要注意线程安全问题。Python提供了多种同步原语来解决线程安全问题。

1. 锁(Lock)

import threading
import time

counter = 0
lock = threading.Lock()

def increment():
    global counter
    for _ in range(1000000):
        with lock:
            counter += 1

# 创建线程
threads = []
for i in range(5):
    t = threading.Thread(target=increment)
    threads.append(t)
    t.start()

# 等待所有线程完成
for t in threads:
    t.join()

print(f"Final counter value: {counter}")

2. 条件变量(Condition)

import threading
import time

condition = threading.Condition()
data = []

def producer():
    for i in range(5):
        with condition:
            data.append(i)
            print(f"Produced: {i}")
            condition.notify()  # 通知消费者
        time.sleep(0.5)

def consumer():
    for _ in range(5):
        with condition:
            while not data:
                condition.wait()  # 等待生产者通知
            item = data.pop(0)
            print(f"Consumed: {item}")

# 创建线程
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)

producer_thread.start()
consumer_thread.start()

producer_thread.join()
consumer_thread.join()

3. 信号量(Semaphore)

import threading
import time

# 最多允许3个线程同时访问
semaphore = threading.Semaphore(3)

def worker(i):
    with semaphore:
        print(f"Worker {i} started")
        time.sleep(1)
        print(f"Worker {i} completed")

# 创建线程
threads = []
for i in range(10):
    t = threading.Thread(target=worker, args=(i,))
    threads.append(t)
    t.start()

# 等待所有线程完成
for t in threads:
    t.join()

print("All workers completed")

进程间通信

由于进程之间不共享内存,需要使用进程间通信(IPC)机制来交换数据。

1. 队列(Queue)

import multiprocessing
import time

def producer(queue):
    for i in range(5):
        queue.put(i)
        print(f"Produced: {i}")
        time.sleep(0.5)

def consumer(queue):
    for _ in range(5):
        item = queue.get()
        print(f"Consumed: {item}")
        time.sleep(1)

# 创建队列
queue = multiprocessing.Queue()

# 创建进程
producer_process = multiprocessing.Process(target=producer, args=(queue,))
consumer_process = multiprocessing.Process(target=consumer, args=(queue,))

producer_process.start()
consumer_process.start()

producer_process.join()
consumer_process.join()

2. 管道(Pipe)

import multiprocessing
import time

def sender(conn):
    for i in range(5):
        conn.send(i)
        print(f"Sent: {i}")
        time.sleep(0.5)
    conn.close()

def receiver(conn):
    while True:
        try:
            item = conn.recv()
            print(f"Received: {item}")
            time.sleep(1)
        except EOFError:
            break

# 创建管道
parent_conn, child_conn = multiprocessing.Pipe()

# 创建进程
sender_process = multiprocessing.Process(target=sender, args=(child_conn,))
receiver_process = multiprocessing.Process(target=receiver, args=(parent_conn,))

sender_process.start()
receiver_process.start()

sender_process.join()
receiver_process.join()

3. 共享内存(Shared Memory)

import multiprocessing
import time

def increment(counter):
    for _ in range(1000000):
        with counter.get_lock():
            counter.value += 1

# 创建共享内存
counter = multiprocessing.Value('i', 0)

# 创建进程
processes = []
for i in range(5):
    p = multiprocessing.Process(target=increment, args=(counter,))
    processes.append(p)
    p.start()

# 等待所有进程完成
for p in processes:
    p.join()

print(f"Final counter value: {counter.value}")

线程池和进程池

使用线程池和进程池可以更高效地管理线程和进程。

1. 线程池

import concurrent.futures
import time

def worker(i):
    print(f"Worker {i} started")
    time.sleep(1)
    print(f"Worker {i} completed")
    return i * 2

# 创建线程池
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    # 提交任务
    futures = [executor.submit(worker, i) for i in range(10)]
    
    # 收集结果
    results = [future.result() for future in concurrent.futures.as_completed(futures)]

print(f"Results: {results}")

2. 进程池

import concurrent.futures
import time

def worker(i):
    print(f"Worker {i} started")
    time.sleep(1)
    print(f"Worker {i} completed")
    return i * 2

# 创建进程池
with concurrent.futures.ProcessPoolExecutor(max_workers=3) as executor:
    # 提交任务
    futures = [executor.submit(worker, i) for i in range(10)]
    
    # 收集结果
    results = [future.result() for future in concurrent.futures.as_completed(futures)]

print(f"Results: {results}")

多线程与多进程的选择

适合使用多线程的场景

  1. I/O密集型任务:如文件操作、网络请求等,因为线程在等待I/O操作时会释放GIL,允许其他线程执行。
  2. 需要共享内存的任务:线程之间共享内存,数据交换更高效。
  3. 启动速度快的任务:线程的启动速度比进程快。

适合使用多进程的场景

  1. CPU密集型任务:如数学计算、图像处理等,因为多进程可以利用多核CPU,避免GIL的限制。
  2. 需要隔离的任务:进程之间相互隔离,一个进程崩溃不会影响其他进程。
  3. 需要大量内存的任务:每个进程有自己的内存空间,避免内存竞争。

多线程和多进程与Rust的对比

相似之处

  • 都支持并发执行任务
  • 都提供了同步原语来解决并发问题
  • 都支持线程池和进程池
  • 都可以处理I/O密集型和CPU密集型任务

不同之处

  • Python的多线程受GIL限制,而Rust的线程没有此限制
  • Python的多进程启动较慢,而Rust的线程启动较快
  • Python的并发模型相对简单,而Rust的并发模型更加安全和强大
  • Python的多线程和多进程使用不同的模块,而Rust的并发功能集成在标准库中

实战案例:使用多线程和多进程处理任务

import concurrent.futures
import time
import requests

# 模拟I/O密集型任务
def fetch_url(url):
    response = requests.get(url)
    return url, response.status_code

# 模拟CPU密集型任务
def compute_factorial(n):
    result = 1
    for i in range(1, n + 1):
        result *= i
    return n, result

def main():
    # 测试I/O密集型任务(使用线程池)
    urls = [
        "https://www.google.com",
        "https://www.github.com",
        "https://www.python.org",
        "https://www.rust-lang.org",
        "https://www.youkuaiyun.com"
    ]
    
    print("Testing I/O密集型任务 with ThreadPoolExecutor:")
    start_time = time.time()
    
    with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
        results = list(executor.map(fetch_url, urls))
    
    for url, status_code in results:
        print(f"{url}: {status_code}")
    
    print(f"I/O密集型任务 took {time.time() - start_time:.2f} seconds")
    
    # 测试CPU密集型任务(使用进程池)
    numbers = [100000, 200000, 300000, 400000, 500000]
    
    print("\nTesting CPU密集型任务 with ProcessPoolExecutor:")
    start_time = time.time()
    
    with concurrent.futures.ProcessPoolExecutor(max_workers=5) as executor:
        results = list(executor.map(compute_factorial, numbers))
    
    for n, result in results:
        print(f"{n}! has {len(str(result))} digits")
    
    print(f"CPU密集型任务 took {time.time() - start_time:.2f} seconds")

if __name__ == "__main__":
    main()

总结

Python的多线程和多进程是一种强大的工具,它们可以帮助我们并发执行任务,提高程序的性能。通过threading和multiprocessing模块,我们可以轻松地创建和管理线程

Python并发编程实践:asyncio与多进程深度解析 在单核处理器时代,程序性能提升主要依赖时钟频率的提升。但随着摩尔定律逐渐失效(2005年后CPU主频增长停滞),单核性能提升空间收窄至每年约3%。结构化并发:引入类似Trio的nursery概念,确保所有子任务在父任务退出前完成。分布式任务队列:集成Celery与asyncio,支持跨节点任务分发。跨语言互操作:通过PyO3与Rust集成,提升异步任务性能。性能优化:asyncio核心性能提升40%适用场景:GUI事件处理、轻量级IO任务。优势:超高并发密度(可管理10K+任务) 阅读详情

相关推荐

Python并发编程全景解析:多线程、多进程与协程的深度对比

随着计算机硬件性能的提升和应用需求的多样化,并发编程在软件开发中扮演着越来越重要的角色。Python作为一种广泛使用的高级编程语言,提供了多种并发编程模型,包括多线程、多进程和协程。本文将深入分析Python中的这三种并发模型,详细探讨它们各自的工作机制、优缺点以及适用场景。通过丰富的代码示例和详尽的解释,本文旨在帮助开发者全面理解Python并发编程的核心概念,掌握选择合适并发模型的方法,从而在实际项目中实现高效、可靠的并发处理。文章还将结合数学公式,对比不同模型在性能和资源利用方面的表现,提供科学的决策

一个被知识诅咒的人 1114

Python-多线程-全局解释器锁 GIL-运行机制-全局变量-多进程调用

全局变量:模块内、所有函数外、所有class外。 局部变量:函数内、class的方法(类方法、静态方法、实例方法)内,且变量前面没有修饰。 类变量:class内,不在class的任何方法内。 实例变量:class的方法内,使用self修饰。如果在print_str函数中没有使用global关键字显式引用全局变量,在print_str函数中将优先使用局部变量,而不是全局变量。 1.2.省略global关键字 当你的函数里只读取全局变量的值,此时可省略global,Python解释器明白你访问的是全局变量。 1

插件开发 855

Python高频面试题2 - 对于计算密集型和IO密集型任务分别应该怎么处理?为什么这样处理?

Python高频面试题2 - 对于计算密集型和IO密集型任务分别应该怎么处理?为什么这样处理?

孤寒者的博客 1万+

多线程 vs 多进程:深度解析与场景选型指南

选择多线程还是多进程,并非单纯的技术偏好,而是对任务特性和运行环境I/O 密集型(等待为主):首选多线程。它轻量、高效,能完美掩盖 I/O 延迟。在 Python 中,也可考虑Asyncio以获得更高性能。CPU 密集型(计算为主):Python/ Ruby 等有 GIL 的语言:必须选多进程以利用多核。Java/ C++/ Go 等无 GIL 的语言多线程通常是首选,因为开销更小且能利用多核,除非需要极高的隔离性。高可靠性要求:无论任务类型,若单个任务崩溃不可接受,多进程提供的隔离性是更好的选择。

2603_94941239的博客 514

章节九:Python进阶主题

这是章节九的补充内容,涵盖了Python进阶主题,包括并发编程和异步IO、数据科学和机器学习、网络爬虫和数据抓取,以及自然语言处理和文本分析。这些主题将帮助你进一步扩展和应用Python的能力,解决更加复杂和实际的问题。自然语言处理(NLP)和文本分析是处理文本数据的重要领域。并发编程和异步IO是处理高并发和高性能需求的重要主题。Python在数据科学和机器学习领域有广泛应用。网络爬虫和数据抓取是获取互联网上数据的常见需求。9.2 数据科学和机器学习。9.3 网络爬虫和数据抓取。

qq_27280353的博客 128

C#教程

C# 教程 C# 是一个简单的、现代的、通用的、面向对象的编程语言,它是由微软(Microsoft)开发的。 本教程将告诉您基础的 C# 编程,同时将向您讲解 C# 编程语言相关的各种先进理念。 现在开始学习 C#! C# 在线工具 谁适合阅读本教程? 本教程有助于初学者理解基础的 C# 编程。在学习完本教程后,您将到达一个中级的 C# 编程水平。

zm1_1zm 1万+

Python 并发编程的深度解析与优化策略

Python 的并发编程为开发者提供了强大的工具和灵活的解决方案。通过深入了解各种并发模型及其应用场景,结合合理的优化策略,可以显著提升程序的性能和稳定性。希望本文能为读者提供有价值的参考,助力他们在并发编程领域取得更大的进步。```

2501_91164862的博客 433

使用Matlab进行IEEE 33节点潮流计算的NR法实现详解及应用实例

IEEE 33节点系统是一个标准的配电系统模型,广泛用于学术研究和工程应用。该系统由33个节点和37条线路组成,结构复杂,具有代表性。其潮流计算结果可用于验证各种潮流计算方法的准确性和效率。NR法是一种基于迭代求解的潮流计算方法,通过不断迭代求解非线性方程组,直到达到预定的收敛条件。NR法具有收敛速度快、计算精度高的优点,适用于大规模复杂电力系统的潮流计算。

m0_57781768的博客 2071

Python 网络编程核心库 —— socketserver 深度解析

Python的socketserver模块为网络编程提供了高效封装,通过面向对象和回调机制简化了服务器开发。它包含TCPServer、UDPServer等服务器类,支持多线程/多进程并发处理,开发者只需继承BaseRequestHandler实现handle()方法即可处理业务逻辑。文章展示了TCP/UDP服务器示例、并发实现方案,以及聊天室和文件服务器等应用场景,帮助开发者快速构建可扩展的网络服务。

萧鼎的博客 1040

在昇腾910B服务上部署搭建适配PDF解析工具Mineru2.5开源项目

本文介绍了在昇腾910B服务器上部署开源PDF解析工具Mineru2.5的过程。首先从昇腾社区下载mindie镜像并运行容器,安装系统依赖。针对部署过程中遇到的多个报错问题(如torchvision与torch版本不匹配、昇腾软件栈与NumPy 2.0不兼容等),提供了具体解决方案和兼容版本。通过设置环境变量、安装指定版本的Python依赖包,成功部署Mineru项目并下载模型。最后运行测试,验证了在NPU设备上运行pipeline的可行性。整个过程详细记录了版本适配和错误处理方法,为类似部署场景提供了参考

一起加油吧 2165

(赛事-2022)[re:Invent 2018]-002:通过分析log多次迭代优化奖励函数后- 最快7.6s / 圈

Deepracer training 流程

Rainbow 4715

爬虫基本功---面试宝典

基本知识点的梳理 一. python 的基本功 简述python的特点和优点; python 是一门开源的解释性语言,相比于Java C++, python具有动态的特性,非常的灵活。 python有那些数据类型: python有六种内置的数据类型,其中不可变得数据类型有:int整数,str字符串,tupel元组,可变的数据类型;dict字典,list列表,set集合。 列表和元组得区别: 列...

weixin_44090435的博客 386

【毕业设计】_基于STM32单片机的按摩椅( 原理图+源码)

按摩器系统基于STM32单片机设计,作为核心控制单元。系统配备了OLED显示屏、蓝牙模块、喇叭模块、播报模块和光电感应模块。光电感应器用于检测是否有人接近,同时,系统可以通过蓝牙接收控制指令并执行相应的操作。该系统支持40℃的热敷功能以及气囊按摩功能,具备温度显示功能,并且可以通过按键切换不同的按摩模式。当光电感应器检测到有人时,按摩椅会自动启动。使用DHT11传感器的红色按钮可以调整温度。

2401_85381100的博客 724

Python并发编程深度解析:多线程、多进程与协程的全面对比

随着应用程序需求的不断增长,尤其是在高并发、高性能计算场景下,掌握有效的并发编程技术成为Python开发者的必备技能。Python提供了多种并发编程模型,包括多线程、多进程和协程,每种模型在不同的应用场景下各有优劣。本文将深入分析这三种并发模型的工作原理、优缺点以及适用场景,通过详细的代码示例和中文注释,帮助读者全面理解并选择最适合自己项目的并发方案。同时,文章还将探讨Python的全局解释器锁(GIL)对并发模型的影响,并介绍一些优化技巧,以提高Python应用的性能和响应速度。无论是初学者还是有经验的开

一个被知识诅咒的人 1610

GD32F103实战:用ADC+DMA实现高精度多通道电压采集与OLED实时显示(附完整工程)

本文详细介绍了如何利用GD32F103的ADC+DMA技术实现高精度多通道电压采集,并通过OLED实时显示数据。文章包含硬件架构设计、ADC配置技巧、DMA传输优化及显示系统实现方案,提供完整工程代码和调试指南,适用于工业传感器和环境监测设备开发。

weixin_42567497的博客 402

海康VisionMaster零代码开发实战:从PLC工程师到视觉专家的捷径

本文为PLC工程师提供了利用海康VisionMaster视觉平台实现零代码视觉开发的实战指南。文章详细阐述了如何通过图形化流程设计替代传统编程,快速搭建视觉检测应用,并实现与PLC的无缝通讯,是工程师从设备控制迈向视觉系统集成的有效捷径。

weixin_29201859的博客 293

Python中的多线程与多进程—性能提升的技巧

多线程和多进程是Python并发编程中两种重要的技术,它们各有优缺点,适用于不同的场景。在实际应用中,合理选择并发技术、优化线程和进程的数量、避免过度上下文切换,并使用高效的数据结构和算法是提高并发程序性能的关键。通过本篇文章的代码示例和实践指导,你可以更深入地理解多线程和多进程的工作原理,并应用这些技术来优化你的Python程序,提升其执行效率。并发编程虽然复杂,但掌握了基本原理和技巧后,可以为你的项目带来显著的性能提升。

一键难忘的博客 4168

实战指南:Qwen3-ASR-1.7B 语音识别

本文介绍了Qwen3-ASR语音识别模型的安装与使用。

举世誉之而不加劝,举世非之而不加沮,定乎内外之分,辩乎荣辱之境,斯已矣。 1809

Python多线程与多进程性能对比:从原理到实战的深度解析

多线程与多进程的选择,本质是空间换时间与时间换空间的权衡艺术。在CPU密集型战场,多进程是无可争议的王者;而在I/O密集型领域,多线程则以轻量级优势称雄。真正的Python高手,懂得根据任务特性动态组合这些武器,构建出既能高效利用硬件资源,又易于维护的并发架构。行动建议我的任务是CPU密集还是I/O密集?需要处理的数据量有多大?系统的内存资源是否充足?答案将指引你走向正确的并发之路。

这家伙很懒,什么都没有留下 814

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Python中的并发编程:多线程与多进程的比较

在Python编程领域中,处理并发任务是提高程序性能的关键之一。本文将探讨Python中两种常见的并发编程方式:多线程和多进程,并比较它们的优劣之处。通过代码实例和详细的解析,我们将深入了解这两种方法的适用场景和潜在问题。

一键难忘的博客 4558

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Python 多线程 vs 多进程:到底该用哪个?

线程是进程中的最小执行单元,同一进程内的多个线程共享进程的内存空间。多线程编程的特点是轻量级,线程间切换开销较小,适合 I/O 密集型任务。

m0_69441654的博客 1386

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Python并发编程深度解析:多线程、多进程与协程的选择

在现代软件开发中,并发编程已成为提升程序性能的重要手段。Python虽然因GIL(全局解释器锁)的存在在并发处理上有一定限制,但依然提供了多种并发编程方案:多线程(Threading)、多进程(Multiprocessing)和协程(Asyncio)。本文将深入分析这三种方案的特点、优缺点及适用场景,帮助开发者在不同情况下做出最佳选择。

exlink2012的专栏 897

Python多线程和多进程

开发服务器默认多线程、单进程,适合开发调试;生产环境应使用多进程 + 线程的成熟部署方案以保证稳定性、并发性和可扩展性。

zkw54334的博客 894

Python编码系列—Python多线程与多进程:并发编程的艺术

在现代软件开发中,充分利用系统资源,提高程序性能是开发者的不懈追求。Python的多线程和多进程作为两种并发执行手段,各自在不同的应用场景下发挥着重要作用。本文将深入探讨Python的多线程与多进程原理、使用场景,并结合实际代码样例,展示它们在项目开发中的应用。多线程是指在单个进程内并行执行多个线程,线程间共享进程的内存空间和资源。而多进程则是操作系统中同时执行多个独立的进程,每个进程拥有自己的内存空间和系统资源。

u013889591的专栏 1273

江大白 | 万字长文,深度梳理Python多线程与多进程(建议收藏 !)

在Python中,多线程和多进程都是用于实现并行处理的方式,它们提供了在单个进程内或跨多个进程执行并发操作的网关,提高了系统的速度和效率。很多同学对其中的原理,并不是特别了解,本文系统性的讲解其中的各个知识点,希望对大家有帮助!

csdn_xmj的博客 1312
上一篇: Python生成器和迭代器深度解析
下一篇: Python类型提示(Type Hints)实战指南
第一程序员
博客等级 码龄1年 1万+粉丝 1822原创
评论 9
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值