【总结】Python并发:多线程、多进程、协程

备注

2025/08/15 星期五
最近用到了python的多线程发现和其他语言有点不同记录一下

一、基本概念

首先要理解一下线程、进程和协程的概念
线程(Thread):是计算机能够调度的最小计算单位
进程(Process):是正在运行的程序,拥有独立的内存空间
协程(Coroutine):是由编程语言在用户态显式调度的轻量级调度机制,不经过操作系统内核的调度

再来看一下我们编程中最常遇到的问题,就是当程序进行一个耗时任务时,程序就不能进行其他任务了,这就有了并发的概念
并发(Concurrency):是在同一时间内具有处理多个任务的能力

并发是一种能力,要想实现并发有两种思路:
并行(Parallelism):是同一时间同时执行多个任务,如:多进程和多线程
异步(Asynchronous):是发起一个耗时任务后,​​不阻塞执行流程等待结果返回​​,继续执行其他操作,如:​​回调、协程
(类似的在硬件层面,操作系统可以通过CPU单核的分时复用或者CPU多核的并行来实现并发。分时复用与异步有相似之处但不相比)

并发的应用场景主要有两类:
CPU密集型:需要把一个大型计算任务拆分成多个小任务​​同时​​计算,优先采用并行思路,场景一般是科学计算、多媒体处理、机器学习、数据分析、密码学运算、项目编译
IO密集型:在进行网络、磁盘等耗时的I/O操作时,优先采用异步思路,场景一般是Web服务的API接口、实时通信、数据爬虫、服务间通信

二、多线程

1.基本用法

python标准库提供了threading模块来实现多线程操作,使用多线程的方式有两种:直接使用Thread类构造函数传入要实现多线程的函数和继承Thread类并重写run方法

import threading

# 传入函数
def my_task():
	pass
def main():
	my_thread = threading.Thread(target=task)

# 继承重写
class MyThread(threading.Thread):        
    def run(self):
        pass
def main():
	my_thread = MyThread()

创建完成后可以使用start()方法开启线程,用join()方法等待线程结束

my_thread.start()
my_thread.join()

2.线程池

python标准库提供了concurrent.futures模块来实现线程池操作,为了提高程序的效率和资源利用率,一般会采用线程池的方式实现多线程,通过预先创建并复用一组线程,可以降低线程创建销毁的成本,提供任务队列机制统一管理线程资源,避免无限制创建线程导致资源耗尽

from concurrent.futures import ThreadPoolExecutor, as_completed

def task(param1, param2):
	pass
def main():
	with ThreadPoolExecutor(max_workers=5) as executor:
		workers= {executor.submit(task, param1, param2): i for i in range(10)}
	
	for worker in as_completed(workers):
		print(worker.result())

3.GIL问题

全局解释器GIL是解释器内部的一个互斥锁,用于同一时间仅允许一个线程执行字节码,导致python多线程无法利用多核实现正真的多线程并发。GIL用于简化python解释器的实现,保证线程安全。因此也导致了python的多线程程序在处理CPU密集型场景时可能不仅没有性能提高反而比单线程性能更差,对IO密集型场景一般不会有太大影响。
GIL并不会被取消,出于历史兼容原因,并且取消GIL可能会导致单线程性能下降,因此对于CPU密集型场景可以优先考虑使用python的多进程方式实现。

三、多进程和异步协程

1.多进程

python标准库提供了multiprocessing模块来实现多进程操作

import multiprocessing

def task():
	pass
def main():
	p = multiprocessing.Process(target=worker)
	processes.append(p)
	p.start()
	p.join()

2.异步协程

协程是异步的一种实现方式,python标准库提供了asyncio模块来实现异步操作,

import asyncio

async def task():
    pass

async def main():
	worker = asyncio.create_task(task())
	results = await asyncio.gather(worker)
	
asyncio.run(main())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值