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程序更高效!
相关推荐
IT_陈寒6 分钟前
Vue的响应式让我加班到凌晨,问题竟出在这个不起眼的地方
前端·人工智能·后端
乱码三千18 分钟前
使用 Docker-compose 搭建SRS直播中转服务端
后端·架构·github
y1su18 分钟前
【Leetcode】1477. 找两个和为目标值且不重叠的子数组
数据结构·后端·算法·leetcode·职场和发展
愛芳芳34 分钟前
Swagger2 多环境动态配置实战指南
java·后端·maven·springboot·swagger
JaguarJack1 小时前
PHP 8.6 只是个小版本,三十项弃用却已在为 PHP 9.0 铺路
后端·php·服务端
BingoGo1 小时前
PHP 8.6 只是个小版本,三十项弃用却已在为 PHP 9.0 铺路
后端·php
Bs_MoneyMagnet5 小时前
基于springboot+vue的滑雪场票务与装备租赁系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·毕业设计·计算机毕业设计
AlienZHOU9 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
狗头大军之江苏分军11 小时前
《潮水漫过十七岁》开学了
后端
苏三说技术12 小时前
如何看待GPT-6在UP主众测中碾压夺冠?它是现在最强大模型吗?
后端