Python并发编程:多线程与多进程实战指南

Python并发编程:多线程与多进程实战指南

在Python中处理大量任务时,并发编程能够显著提升程序性能。本文将详细介绍Python中的多线程和多进程技术,帮助你掌握并发编程的核心知识。

一、并发编程基础

1. 什么是并发?

并发是指程序同时处理多个任务的能力。在单核CPU上,这是通过时间片轮转实现的,让不同任务快速切换执行。

2. 多线程 vs 多进程

  • 多线程:共享内存空间,上下文切换快,但存在全局解释器锁(GIL)限制
    • 多进程:独立内存空间,不受GIL限制,但上下文切换开销大

二、多线程实现

1. 创建线程

python 复制代码
  • import threading
  • def worker():
bash 复制代码
print('Thread is working...')
bash 复制代码
# 创建线程
ini 复制代码
thread = threading.Thread(target=worker)
arduino 复制代码
thread.start()
arduino 复制代码
thread.join()
go 复制代码
```
shell 复制代码
### 2. 线程同步
go 复制代码
```python
javascript 复制代码
from threading import Lock, Semaphore
ini 复制代码
lock = Lock()
ini 复制代码
semaphore = Semaphore(3)  # 限制同时访问数量
go 复制代码
```
shell 复制代码
### 3. 线程安全
go 复制代码
```python
bash 复制代码
# 使用 Lock
csharp 复制代码
with lock:
bash 复制代码
    # 线程安全代码
bash 复制代码
    # 使用 Semaphore
markdown 复制代码
    semaphore.acquire()
bash 复制代码
    # 使用后释放
markdown 复制代码
    semaphore.release()
go 复制代码
    ```
bash 复制代码
    ## 三、多进程实现
bash 复制代码
    ### 1. 创建进程
go 复制代码
    ```python
arduino 复制代码
    from multiprocessing import Process
ruby 复制代码
    def worker_process():
bash 复制代码
        print('Process is working...')
bash 复制代码
        # 创建进程
ini 复制代码
        process = Process(target=worker_process)
arduino 复制代码
        process.start()
arduino 复制代码
        process.join()
go 复制代码
        ```
bash 复制代码
        ### 2. 进程间通信
go 复制代码
        ```python
javascript 复制代码
        from multiprocessing import Pipe, Queue
bash 复制代码
        # 使用 Pipe
ini 复制代码
        parent_conn, child_conn = Pipe()
arduino 复制代码
        parent_conn.send('hello')
ini 复制代码
        msg = child_conn.recv()
bash 复制代码
        # 使用 Queue
ini 复制代码
        queue = Queue()
arduino 复制代码
        queue.put('data')
ini 复制代码
        data = queue.get()
go 复制代码
        ```
bash 复制代码
        ### 3. 批量进程
go 复制代码
        ```python
javascript 复制代码
        from multiprocessing import Pool
python 复制代码
        def square(n):
kotlin 复制代码
            return n * n
ini 复制代码
            if __name__ == '__main__':
csharp 复制代码
                with Pool(4) as p:
go 复制代码
                        results = p.map(square, range(10))
scss 复制代码
                                print(results)
go 复制代码
                                ```
bash 复制代码
                                ## 四、实战案例
bash 复制代码
                                ### 1. 并发爬虫
go 复制代码
                                ```python
arduino 复制代码
                                import requests
javascript 复制代码
                                from concurrent.futures import ThreadPoolExecutor
python 复制代码
                                def fetch_url(url):
ini 复制代码
                                    response = requests.get(url)
arduino 复制代码
                                        return response.text
ini 复制代码
                                        urls = ['https://example.com', 'https://juejin.cn']
csharp 复制代码
                                        with ThreadPoolExecutor(max_workers=5) as executor:
ini 复制代码
                                            results = list(executor.map(fetch_url, urls))
scss 复制代码
                                                print(results)
go 复制代码
                                                ```
bash 复制代码
                                                ### 2. 并发计算
go 复制代码
                                                ```python
javascript 复制代码
                                                from multiprocessing import Pool
arduino 复制代码
                                                import time
python 复制代码
                                                def compute(n):
css 复制代码
                                                    time.sleep(1)
kotlin 复制代码
                                                        return n * n
ini 复制代码
                                                        if __name__ == '__main__':
csharp 复制代码
                                                            with Pool(4) as p:
go 复制代码
                                                                    results = p.map(compute, range(10))
scss 复制代码
                                                                        print(results)
go 复制代码
                                                                        ```
bash 复制代码
                                                                        ## 五、性能优化建议
markdown 复制代码
                                                                        1. **避免在I/O密集型任务中使用GIL**:使用多线程处理网络请求
markdown 复制代码
                                                                        2. **计算密集型任务使用多进程**:充分利用多核CPU
markdown 复制代码
                                                                        3. **合理设置线程/进程数量**:根据CPU核心数调整
markdown 复制代码
                                                                        4. **使用异步IO**:对于IO密集型任务,考虑asyncio
bash 复制代码
                                                                        ## 六、总结
markdown 复制代码
                                                                        并发编程能够显著提升Python程序的性能,但需要根据实际场景选择合适的技术:
markdown 复制代码
                                                                        - **I/O密集型任务**:优先考虑多线程
markdown 复制代码
                                                                        - **计算密集型任务**:优先考虑多进程
markdown 复制代码
                                                                        - **复杂场景**:考虑异步IO或混合方案
markdown 复制代码
                                                                        掌握这些技术,让你的Python程序更高效!
相关推荐
万少6 分钟前
用 TraeWork 给小孩做一个家庭工作台
前端·人工智能·后端
2601_9638701819 分钟前
【计算机毕业设计】基于Vue + Spring Boot的社区养老服务管理平台设计与实现
spring boot·后端·课程设计
前端开发张小七34 分钟前
Java 学习笔记 · 第二课:面向对象核心(封装、继承、多态)及接口与异常
java·后端·程序员
颜进强39 分钟前
Calude Code - 23 用 MCP 把 Jenkins 变成 AI 队友:一次对话完成自动化发布
前端·后端
Awna1 小时前
Golang 大小写可见性规范
开发语言·后端·golang
神奇小汤圆1 小时前
分布式事务没有银弹:从CAP定理到AT与TCC模式的选择指南
后端
YuePeng1 小时前
不写一行接口,让 DBeaver 直连你的指标层——背后只用了一个端口
后端·架构·github
董员外2 小时前
RAG 系统进化论(七):Multimodal RAG(多模态 RAG),当知识存在于表格、图片和页面中
人工智能·后端·设计模式
用户667675093792 小时前
Java 是如何操作Redis的?从 Spring Data Redis中RedisTemplate 源码分析 ZSet 调用链
后端
凌虚3 小时前
Kubernetes 编年史:从 Borg 到云原生操作系统
后端·程序员·kubernetes