Python协程和线程的区别

大佬的理解

在这里插入图片描述

我的理解

多线程是通过cpu分片实现并行,所有线程雨露均沾(可能操作系统有优化,但本质还是这个),比如一个线程执行到request请求时等待响应,假如响应需要60秒,很快就因为分片到时而释放cpu,但很快该线程又会被分配新的分片又会一直执行到分片到时,循环往复,也就是说这60秒内分配给该线程的cpu分片都是无效的! 协程是通过程序控制调度,当执行io时,可以通过await关键字来避免给任务分配cpu分片,提高cpu的效率。

测试验证

现在有一个需求:需要http请求一个接口100次,假如接口耗时1秒。
多线程和协程分别来实现,有什么区别呢?

在这里插入图片描述
可以看到同样是并发,协程的效率远比多线程要好的多!

源码:

多线程:

import concurrent
import time
from concurrent.futures import ThreadPoolExecutor


def request():
    # 模拟request请求
    time.sleep(1)
    return 1


def concurrent_execution():
    with ThreadPoolExecutor(max_workers=10) as executor:
        futures = {executor.submit(request) for _ in range(100)}
        results = []
        for future in concurrent.futures.as_completed(futures):
            result = future.result()
            results.append(result)
        return sum(results)


start_time = time.time()
ret = concurrent_execution()
print(f'ret:{ret}, time: {time.time() - start_time}')

协程:

import asyncio
import time


async def aiohttp():
    # 模拟aiohttp请求
    await asyncio.sleep(1)
    return 1


async def concurrent_execution():
    tasks = [asyncio.create_task(aiohttp()) for _ in range(100)]
    rets = await asyncio.gather(*tasks)
    return sum(rets)


start_time = time.time()
ret = asyncio.run(concurrent_execution())
print(f'ret:{ret}, time: {time.time() - start_time}')

注意点

协程避免了【雨露均沾】带来的性能问题,但是需要注意也失去了【雨露均沾】的好处!!!
比如当其他协程一直在运行,而不await(例如下面示例中time.sleep(5)),这时其他协程是没有机会执行的!

在这里插入图片描述
可以看到这个示例中,使用多线程时,子线程不会一直等待主线程的sleep,而协程方案会一直等到知道主任务完成。

总计

在使用协程时,尽量不要阻塞,比如调用接口、访问数据库等使用非阻塞的工具包,否则性能不仅得不到提升,反而大大降低了吞吐量(多线程至少还能有机会处理)!假如必须阻塞,那还不如使用多线程!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值