寒假打卡19-2月5日

Python 并发编程

在本篇文章中,我们将介绍 Python 中的并发编程,包括线程、进程、协程,以及全局解释器锁(GIL)和其影响。这些知识将帮助你编写高效的并发程序,充分利用多核处理器的优势。

1. 线程(threading)

基础概念

线程是操作系统能够进行运算调度的最小单位,多个线程可以共享同一个进程的内存空间,从而实现资源共享和任务并行。

使用 threading 模块

Python 提供了 threading 模块来创建和管理线程。

import threading

def print_numbers():
    for i in range(5):
        print(i)

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

线程同步

使用 threading.Lock 实现线程同步,防止多个线程同时访问共享资源时发生冲突。

import threading

lock = threading.Lock()
counter = 0

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

threads = [threading.Thread(target=increment) for _ in range(10)]
for thread in threads:
    thread.start()
for thread in threads:
    thread.join()

print(counter)  # 输出: 100000

2. 进程(multiprocessing)

基础概念

进程是资源分配的基本单位,每个进程拥有独立的内存空间。Python 提供了 multiprocessing 模块来创建和管理进程。

使用 multiprocessing 模块

import multiprocessing

def print_numbers():
    for i in range(5):
        print(i)

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

进程间通信

使用 multiprocessing.Queue 实现进程间通信。

import multiprocessing

def producer(queue):
    for i in range(5):
        queue.put(i)

def consumer(queue):
    while not queue.empty():
        print(queue.get())

queue = multiprocessing.Queue()
process1 = multiprocessing.Process(target=producer, args=(queue,))
process2 = multiprocessing.Process(target=consumer, args=(queue,))

process1.start()
process1.join()
process2.start()
process2.join()

3. 协程(asyncio)

基础概念

协程是一种比线程更轻量级的并发实现方式,适用于 I/O 密集型任务。Python 提供了 asyncio 模块来创建和管理协程。

使用 asyncio 模块

import asyncio

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

# 创建事件循环
loop = asyncio.get_event_loop()
# 运行协程
loop.run_until_complete(print_numbers())

协程与任务

使用 asyncio.create_task 创建任务,并使用 await 等待任务完成。

import asyncio

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

async def main():
    task1 = asyncio.create_task(print_numbers())
    task2 = asyncio.create_task(print_numbers())
    await task1
    await task2

# 创建事件循环并运行主协程
asyncio.run(main())

4. 全局解释器锁(GIL)

概念

全局解释器锁(GIL)是 CPython 解释器中的一个机制,确保同一时间只有一个线程执行 Python 字节码,从而保证线程安全。

影响

由于 GIL 的存在,多线程在 CPU 密集型任务中的性能提升有限,反而可能因为上下文切换而降低性能。然而,在 I/O 密集型任务中,多线程仍然能够提高性能。

解决方案

对于 CPU 密集型任务,可以使用 multiprocessing 模块,通过多进程实现并行计算,绕过 GIL 的限制。

import multiprocessing

def cpu_bound_task(n):
    result = 0
    for i in range(n):
        result += i * i
    return result

if __name__ == "__main__":
    with multiprocessing.Pool() as pool:
        results = pool.map(cpu_bound_task, [1000000] * 4)
        print(results)

总结

在本篇文章中,我们介绍了 Python 中的并发编程,包括线程、进程、协程,以及全局解释器锁(GIL)和其影响。通过学习这些知识,你能够编写高效的并发程序,充分利用多核处理器的优势。接下来,我们将探讨 Python 网络请求的相关内容,敬请期待!

posted @ 2025-02-05 09:10  aallofitisst  阅读(16)  评论(0)    收藏  举报