写代码总会遇到这种情况 -程序慢得像蜗牛,用户等得直跺脚。这时候就得考虑并发编程了。不过说实话,并发编程确实不太容易理解,很多小伙伴一听这词就头大。今天咱们就聊聊Python并发编程那些事儿。
什么是并发编程
并发(Concurrency)说白了就是同时处理多个任务。打个比方,你在煮面的时候还能刷刷手机,这就是并发。在Python里面主要有这三种实现方式:多线程、多进程和异步IO。
1import threading
2import time
4def cook_noodles():
5 print(“下锅煮面中...”)
6 time.sleep(2) # 模拟煮面需要的时间
7 print(“面煮好了!”)
9def watch_phone():
10 print(“刷手机中...”)
11 time.sleep(1) # 模拟刷手机的时间
12 print(“刷完手机了!”)
14# 创建两个线程
15t1 = threading.Thread(target=cook_noodles)
16t2 = threading.Thread(target=watch_phone)
18# 启动线程
19t1.start()
20t2.start()
22# 等待两个线程都结束
23t1.join()
24t2.join()
多线程编程
多线程就像是一个程序里分身出好几个自己。每个线程能独立工作,但是都共用同一块内存空间。
1import threading
2import time
3from queue import Queue
5# 创建一个队列用于存储数据
6data_queue = Queue()
8def producer():
9 for i in range(5):
10 data_queue.put(f“数据{i}”)
11 print(f“生产者生产了: 数据{i}”)
12 time.sleep(0.5)
14def consumer():
15 while True:
16 if data_queue.empty():
17 break
18 data = data_queue.get()
19 print(f“消费者消费了: {data}”)
20 time.sleep(1)
22# 创建生产者和消费者线程
23p = threading.Thread(target=producer)
24c = threading.Thread(target=consumer)
26p.start()
27c.start()
小贴士:
多线程共享内存空间,要特别注意线程安全问题
用锁(Lock)来保护共享资源
Python的GIL限制了多线程在CPU密集型任务上的性能
多进程编程
多进程就厉害了,每个进程都有独立的内存空间,互不干扰。CPU密集型的任务用多进程准没错。
1from multiprocessing import Process, Pool
2import os
4def heavy_calculation(n):
5 result = 0
6 for i in range(n):
7 result += i * i
8 print(f“进程{os.getpid()}计算完成”)
9 return result
11if __name__ == '__main__':
12 # 创建进程池
13 pool = Pool(processes=4)
15 # 提交多个任务
16 numbers = [1000000, 2000000, 3000000, 4000000]
17 results = pool.map(heavy_calculation, numbers)
19 pool.close()
20 pool.join()
异步IO编程
异步IO是个特别巧妙的东西,它不是真的同时做多件事,而是在等待的时候去做别的事情。就像你等外卖的时候可以先做别的事。
1import asyncio
3async def fetch_data():
4 print(“开始获取数据...”)
5 await asyncio.sleep(2) # 模拟IO操作
6 print(“数据获取完成!”)
7 return “一些数据”
9async def process_data():
10 print(“开始处理数据...”)
11 await asyncio.sleep(1) # 模拟数据处理
12 print(“数据处理完成!”)
14async def main():
15 # 并发执行两个协程
16 task1 = asyncio.create_task(fetch_data())
17 task2 = asyncio.create_task(process_data())
18 await asyncio.gather(task1, task2)
20asyncio.run(main())
小贴士:
异步IO主要用于IO密集型任务
async/await是Python3.5引入的语法糖
不要在协程中放CPU密集型任务,会阻塞事件循环
到这基本就说完了,其实并发编程没那么可怕,关键是要搞清楚每种方式的特点和应用场景。平时写代码记得多练习,遇到性能问题就可以考虑用并发来优化。对了,写并发代码时一定要注意安全性,不然程序出了问题可不好找原因。
领取专属 10元无门槛券
私享最新 技术干货