当前位置: 首页 > news >正文

python基础语法14-多线程与多进程

Python 多线程与多进程详解

在 Python 中,多线程多进程是常用的并发编程技术,它们可以帮助程序在处理大量任务时提高效率。Python 提供了多个模块来支持多线程和多进程的开发,包括 threadingmultiprocessingasyncio。本文将详细介绍这些模块的基本用法和它们的应用场景。


1. 多线程:threading 模块

多线程(Multithreading)是一种轻量级的并发机制,允许程序同时执行多个任务。Python 中的 threading 模块提供了用于创建和管理线程的功能。多线程适合于 I/O 密集型任务,比如文件读取、网络请求等。

1.1 创建线程

我们可以通过 threading.Thread 类创建新线程,并使用 start() 启动线程,使用 join() 等待线程结束。

import threading
import time

def print_numbers():
    for i in range(5):
        time.sleep(1)
        print(i)

# 创建线程
thread = threading.Thread(target=print_numbers)
# 启动线程
thread.start()
# 等待线程结束
thread.join()

print("Thread has finished.")

输出:

0
1
2
3
4
Thread has finished.

1.2 线程同步与锁

在多线程环境下,多个线程可能会访问共享资源。为了避免数据竞争和不一致性,可以使用锁(Lock)来保证同一时刻只有一个线程可以访问共享资源。

import threading

lock = threading.Lock()

def safe_print():
    with lock:
        for i in range(5):
            print(i)

threads = [threading.Thread(target=safe_print) for _ in range(2)]

for t in threads:
    t.start()

for t in threads:
    t.join()

1.3 GIL(全局解释器锁)

需要注意的是,Python 中的多线程并不适合 CPU 密集型任务,这是因为 Python 有全局解释器锁(GIL)。GIL 确保同一时刻只有一个线程执行 Python 字节码,从而限制了多线程的并行执行能力。在进行 CPU 密集型计算时,使用多进程比多线程更有效。


2. 多进程:multiprocessing 模块

多进程(Multiprocessing)是指通过创建多个进程来执行任务,每个进程拥有独立的内存空间,适用于 CPU 密集型任务,如大数据处理、图像处理等。Python 中的 multiprocessing 模块提供了创建和管理进程的功能。

2.1 创建进程

与多线程类似,我们可以通过 multiprocessing.Process 类来创建新进程。

import multiprocessing
import time

def print_numbers():
    for i in range(5):
        time.sleep(1)
        print(i)

# 创建进程
process = multiprocessing.Process(target=print_numbers)
# 启动进程
process.start()
# 等待进程结束
process.join()

print("Process has finished.")

输出:

0
1
2
3
4
Process has finished.

2.2 进程间通信

在多进程程序中,进程之间无法共享内存。multiprocessing 模块提供了队列(Queue)和管道(Pipe)来实现进程间通信。

import multiprocessing

def worker(q):
    q.put("Hello from the child process")

# 创建队列
queue = multiprocessing.Queue()
# 创建子进程
process = multiprocessing.Process(target=worker, args=(queue,))
process.start()
process.join()

# 获取子进程的结果
print(queue.get())  # 输出: Hello from the child process

2.3 共享内存

multiprocessing 模块也提供了共享内存功能,允许多个进程共享数据。可以使用 ValueArray 来实现共享内存。

import multiprocessing

def increment(shared_value):
    shared_value.value += 1

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

# 创建多个进程
processes = [multiprocessing.Process(target=increment, args=(shared_value,)) for _ in range(5)]

for p in processes:
    p.start()

for p in processes:
    p.join()

print(shared_value.value)  # 输出: 5

3. 异步编程:asyncio 模块

asyncio 是 Python 中的异步编程模块,适用于 I/O 密集型任务,特别是网络编程、数据库访问等场景。asyncio 通过事件循环(event loop)来调度任务,使得程序在执行 I/O 操作时不会阻塞,能够同时处理多个任务。

3.1 基本语法

asyncio 通过 asyncawait 关键字定义异步函数和调用异步任务。

import asyncio

async def print_numbers():
    for i in range(5):
        await asyncio.sleep(1)
        print(i)

# 创建事件循环并运行异步函数
asyncio.run(print_numbers())

输出:

0
1
2
3
4

3.2 并发执行多个任务

asyncio 允许我们同时运行多个异步任务。通过 asyncio.gather(),可以并发地执行多个异步任务。

async def task1():
    await asyncio.sleep(1)
    print("Task 1 finished")

async def task2():
    await asyncio.sleep(2)
    print("Task 2 finished")

async def task3():
    await asyncio.sleep(3)
    print("Task 3 finished")

# 并发执行多个任务
async def main():
    await asyncio.gather(task1(), task2(), task3())

asyncio.run(main())

输出:

Task 1 finished
Task 2 finished
Task 3 finished

3.3 异常处理

在异步编程中,异常也可以通过 try-except 语句捕获和处理。

async def task():
    try:
        await asyncio.sleep(1)
        raise ValueError("Something went wrong")
    except ValueError as e:
        print(f"Caught exception: {e}")

asyncio.run(task())

输出:

Caught exception: Something went wrong

4. 多线程 vs 多进程 vs 异步

特性多线程 (threading)多进程 (multiprocessing)异步编程 (asyncio)
使用场景I/O 密集型任务CPU 密集型任务I/O 密集型任务
并行性受限于 GIL(Python Global Interpreter Lock)真正的并行性(每个进程有独立的内存空间)通过事件循环调度任务,不是并行
内存消耗共享内存,轻量每个进程都有独立内存不占用额外内存,任务共享事件循环
适用情况网络请求、文件操作等 I/O 操作大规模数据处理,计算密集型任务网络编程、数据库访问等 I/O 操作

5. 总结

  • 多线程适合 I/O 密集型任务,但受到 Python GIL 的限制,不适用于 CPU 密集型任务。
  • 多进程适合 CPU 密集型任务,能够充分利用多核 CPU,但需要更多的内存和进程间通信机制。
  • 异步编程通过 asyncio 模块能够高效地处理大量的 I/O 操作,尤其适用于需要并发执行多个任务的场景。

通过选择合适的并发编程方式,可以有效提高程序的性能,特别是在处理大量任务时。

相关文章:

  • 如今做哪些网站能致富今日关注
  • 营口建设工程信息网站东莞网络推广系统
  • 网站业务原创文章代写
  • 怎么做企业网站seo 优化
  • 做网站为什么需要花钱如何推销网站
  • 织梦怎么做英文版网站网络营销首先要进行
  • 校园智能硬件国产化的现状与意义
  • 使用层次聚类算法对wine数据集进行聚类分析
  • Flink的数据流图中的数据通道 StreamEdge 详解
  • 如何保持自己在职场的核心竞争力
  • Python贝叶斯回归、强化学习分析医疗健康数据拟合截断删失数据与参数估计3实例
  • icoding题解排序
  • NO.87十六届蓝桥杯备战|动态规划-完全背包|疯狂的采药|Buying Hay|纪念品(C++)
  • x265 编码器中运动搜索 ME 方法对比实验
  • C++基础精讲-03
  • 苍穹外卖总结
  • 【Web API系列】WebSocketStream API 深度实践:构建高吞吐量实时应用的流式通信方案
  • 23种设计模式生活化场景,帮助理解
  • 洛谷刷题Day1——P1706+P1157+P2089+P3654
  • 要查看 FAISS 使用的 OpenMP 版本,需根据安装方式和系统环境采用不同方法。以下是具体步骤和原理分析:
  • [设计模式]发布订阅者模式解耦业务和UI(以Axios拦截器处理响应状态为例)
  • Spring Boot 自动加载流程详解
  • 8.3.5 ToolStripContainer(工具栏容器)控件
  • 线代第四课:行列式的性质
  • 电子元件浸入式冷却
  • 对重大保险风险测试的算法理解