高并发编程一直是Python开发中的重头戏,掌握它就像给代码插上翅膀,让程序跑得更快更溜。这个知识点说难也不难,说简单也不简单,关键是要搞清楚几个核心概念,上手实践才是王道。
并发和并行傻傻分不清?
好多小伙伴总是搞混并发和并行,我一开始也是一脸懵。打个简单的比方,并发就像你一个人同时玩着手机刷微博、追剧,看似同时在做,实际上是在快速切换;并行就像你和你对象两个人,一个人刷微博一个人追剧,是真的同时在进行。
1import time
2from concurrent.futures import ThreadPoolExecutor
4def task(name):
5 print(f'{name}任务开始...')
6 time.sleep(2) # 模拟耗时操作
7 print(f'{name}任务结束!')
8 return name
10# 创建线程池
11with ThreadPoolExecutor(max_workers=3) as executor:
12 tasks = ['看剧', '刷微博', '玩游戏']
13 results = executor.map(task, tasks)
多线程还是多进程?这是个问题
在Python里面,因为有个叫GIL的东西(全局解释器锁),多线程在CPU密集型任务上表现不咋地。要是遇到计算密集的活儿,多进程更靠谱。
1from multiprocessing import Process
2import os
4def heavy_calc():
5 count = 0
6 for i in range(100_000_000):
7 count += i
8 print(f'进程{os.getpid()}计算完成')
10if __name__ == '__main__':
11 processes = []
12 for _ in range(4):
13 p = Process(target=heavy_calc)
14 processes.append(p)
15 p.start()
17 for p in processes:
18 p.join()
小贴士:
多线程适合IO密集型任务,比如爬虫、文件处理
多进程适合CPU密集型任务,比如大数据计算
别忘了处理异常,不然程序容易挂掉
协程:异步编程的实力选手
协程是我最喜欢的并发方式,轻量级又高效。Python 3.5之后引入的async/await语法糖,用起来贼爽。
1import asyncio
3async def fetch_data(i):
4 print(f'开始获取数据{i}...')
5 await asyncio.sleep(1) # 模拟IO操作
6 print(f'数据{i}获取完成!')
7 return f'data_{i}'
9async def main():
10 tasks = [fetch_data(i) for i in range(5)]
11 results = await asyncio.gather(*tasks)
12 print(f'所有数据:{results}')
14# Python 3.7+
15asyncio.run(main())
线程安全和锁机制
多线程编程最坑的就是共享资源的问题,不加锁容易数据混乱,加锁太多又影响性能,得找到平衡点。
1import threading
3class Counter:
4 def __init__(self):
5 self.count = 0
6 self.lock = threading.Lock()
8 def increment(self):
9 with self.lock:# 使用上下文管理器,自动加解锁
10 temp = self.count
11 temp += 1
12 self.count = temp
14counter = Counter()
15threads = []
16for _ in range(100):
18 threads.append(t)
19 t.start()
小贴士:
能用Lock就别用RLock,性能更好
死锁问题要特别注意,按固定顺序获取多个锁
尽量使用threading.local()存储线程私有数据
Python的并发编程博大精深,今天咱们就聊到这。掌握这些基础概念,再配合实际项目练练手,很快就能上手了。写并发代码最重要的是要有耐心,调试起来可能会很烦,但熟能生巧,代码写多了自然就有感觉了。
代码这东西,光看不练假把式。赶紧动手试试,遇到问题别怕,爬几次坑技术才能提升。
推 荐 阅 读
点赞分享
让钱和爱流向你
领取专属 10元无门槛券
私享最新 技术干货