【python】并发编程——协程

1 一些概念

1.1 协程

执行实体每次执行一个执行流/任务,当前执行流/任务遇阻塞,执行实体切换到其他执行流/任务。执行实体在多个执行流/任务中切换,形成一种并发机制,每个执行流/任务就是一个协程。

1.2 事件循环

直接调用协程返回一个协程对象,并不真正执行协程。协程要在事件循环中被调度执行。事件循环管理协程执行流,当协程阻塞,事件循环将调度其他未阻塞的协程继续执行。
async.run(coro)将启动事件循环并运行主协程coro。await将停止一个阻塞的协程恢复另一个不阻塞的协程。
在这里插入图片描述

2 coroutine in Python

2.1 协程的执行

await coro1()暂停当前协程,切换到协程coro1执行,直到coro1()执行完毕,才恢复main_coro()执行。而对于coro1(),执行到await asyncio.sleep(3),停止执行coro1(),切换执行asyncio.sleep(3)。asyncio.sleep(3)执行耗时3s后,恢复执行coro1(),coro1()执行完毕后切换main_coro执行。这就是切换协程的顺序性。

2.1.1 例子1

import asyncio
import time


async def coro1(x):
    print('coro1 starts!')
    await asyncio.sleep(3)
    print('coro1 ends!')
    return x


async def main_coro():
    print('main_coro starts!')
    ret = await coro1(1)
    print('main_coro1 ends! coro1 return: %d' % ret)


if __name__ == '__main__':
    start_time = time.time()
    asyncio.run(main_coro())
    end_time = time.time()
    print('total cost: %fs' % (end_time - start_time))

'''输出
main_coro starts!
coro1 starts!
coro1 ends!
main_coro1 ends! coro1 return: 1
total cost: 3.002261s
'''

2.1.2 例子2

可以看出这种串行调度并没利用好协程并发处理的优势。可以引入task来应对。

import asyncio
import time


async def fetch_data(data_id: int) -> None:
    print(f'Fetching data for ID {
     
     data_id}'
### Python 并发编程教程与最佳实践 #### 理解并发编程的重要性 在现代计算环境中,高并发应用程序的需求日益增长。Python作为一种流行的语言,在处理并发任务方面提供了丰富的工具和支持[^1]。 #### 主要的并发模型及其特点 Python 支持三种主要的并发模型:线程、进程和异步编程。每种模型都有其独特的优势和局限性: - **线程**:适合用于I/O密集型任务,如网络请求或文件读写。然而,由于全局解释器锁(GIL),CPU密集型任务可能不会从中受益太多。 - **进程**:绕过了GIL的问题,适用于CPU密集型工作负载。但是创建新进程的成本较高,并且涉及更多的资源消耗。 - **异步编程**:利用协程实现了轻量级的任务切换,非常适合于大量短时间等待的操作,比如Web服务器响应客户端请求[^5]。 #### 编码实例展示不同类型的并发方法 ##### 使用 `threading` 模块实现多线程 ```python import threading def task(name): print(f"Thread {name} is running") threads = [] for i in range(3): t = threading.Thread(target=task, args=(i,)) threads.append(t) t.start() for thread in threads: thread.join() ``` ##### 利用 `multiprocessing` 进行多进程操作 ```python from multiprocessing import Process def process_task(name): print(f'Process {name}: starting') if __name__ == '__main__': processes = [Process(target=process_task, args=(f'{i}',)) for i in range(3)] for p in processes: p.start() for p in processes: p.join() ``` ##### 异步函数定义及执行 ```python import asyncio async def async_function(): await asyncio.sleep(1) print('Async function completed.') loop = asyncio.get_event_loop() loop.run_until_complete(async_function()) ``` #### 关键概念和技术要点 当涉及到具体实施时,有几个重要的考虑因素需要牢记: - 对于线程来说,确保任何共享的数据结构都是线程安全的; - 当采用多进程方案时,则需关注跨进程间的有效通讯机制; - 而对于异步编程而言,理解事件循环的工作原理至关重要[^3]。 #### 应对挑战的方法论建议 为了克服并发编程中存在的潜在困难,推荐遵循以下指导原则: - 明确区分任务性质——判断是属于I/O还是CPU绑定类型; - 合理选择合适的并发模式以匹配特定需求; - 探索最新的库更新和发展趋势,以便充分利用改进后的特性[^2];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值