关于python并发编程中的协程
作者:菜鸟小超 发布时间:2023-10-18 04:37:44
什么是协程
协程(Coroutine)是一种比线程更加轻量级的并发方式,它不需要线程上下文切换的开销,可以在单线程中实现并发。协程通常具有以下特点:
协程中的代码可以暂停执行,并且在需要的时候可以恢复执行。
多个协程可以在同一线程中并发执行,但是任意时刻只有一个协程在执行。
协程通常是基于事件循环(Event Loop)实现的,事件循环负责调度协程的执行。
协程和线程
线程和协程都是实现并发编程的方式,但它们有一些不同的特点和应用场景。
**线程是操作系统调度的基本单位,**每个线程都拥有自己的执行上下文,包括线程栈、寄存器等。线程之间的切换需要进行上下文切换,包括保存当前线程的上下文,恢复另一个线程的上下文等操作,这些操作会耗费大量的时间和资源。在多线程编程中,线程切换是非常常见的操作,原因如下:
调度。当多个线程同时执行时,操作系统需要对这些线程进行调度,根据优先级等因素决定当前应该执行哪个线程。线程切换是调度的基本操作之一,通过切换线程,操作系统可以实现多个线程的并发执行。
等待。当一个线程需要等待某个事件发生时,例如等待 IO 操作完成、等待锁释放等,线程可以主动释放 CPU,使其他线程有机会执行。在等待完成后,线程可以被重新唤醒,继续执行。
并发。线程可以实现并发执行的效果,例如一个线程处理网络请求,另一个线程处理用户交互,这样可以提高系统的响应速度和处理能力。
切换到其他线程执行。在某些情况下,线程可能会因为一些原因无法继续执行,例如线程进入了死循环或者发生了异常,这时需要切换到其他线程执行,避免系统崩溃或者出现其他问题。
线程的并发编程通常会受到多线程竞争、死锁、上下文切换等问题的限制。在 Python 中,使用多线程编程需要注意线程安全、GIL 等问题。
协程是一种轻量级的并发方式,它是在用户空间中实现的,并不依赖于操作系统的调度。协程可以在同一个线程中实现并发,不需要进行上下文切换,因此执行效率非常高。协程通常使用事件循环(Event Loop)来调度协程的执行,事件循环会在协程需要等待 IO 操作或者其他协程时,暂停当前协程的执行,执行其他协程,从而实现并发执行的效果。在 Python 中,协程通常使用 asyncio
模块来实现,支持异步 IO、网络编程、任务调度等场景。
相对于线程,协程的主要优点包括:
更加轻量级,占用的资源更少;
不需要进行上下文切换,执行效率更高;
可以使用事件循环进行调度,实现高并发的效果;
不会受到 GIL 的限制,可以更好地利用多核 CPU。
然而,协程也有一些限制,例如无法利用多核 CPU、调试困难等问题。在选择使用线程还是协程时,需要根据具体的应用场景进行选择。
协程的应用
协程可以应用于很多场景,例如:
网络编程:协程可以帮助我们实现高并发的网络应用。
异步IO:协程可以帮助我们高效地处理异步IO操作。
数据库操作:协程可以帮助我们实现高并发的数据库应用。
任务调度:协程可以帮助我们实现高效的任务调度系统。
演示Demo
下面是一个示例代码,演示了如何使用协程和 asyncio
模块来实现一个简单的任务调度:
import asyncio
async def task1():
print("Task 1")
await asyncio.sleep(1)
print("Task 1 done")
async def task2():
print("Task 2")
await asyncio.sleep(2)
print("Task 2 done")
async def task3():
print("Task 3")
await asyncio.sleep(3)
print("Task 3 done")
async def main():
await asyncio.gather(task1(), task2(), task3())
这段代码使用了 Python 的协程和 asyncio
模块,定义了三个协程函数 task1
、task2
、task3
,以及一个主协程函数 main
。每个协程函数打印自己的任务名,然后暂停一段时间。主协程函数使用 asyncio.gather
并发执行了三个协程函数,最终输出结果为:
Task 1
Task 2
Task 3
Task 1 done
Task 2 done
Task 3 done
[Finished in 3.2s]
来源:https://blog.csdn.net/weixin_41777118/article/details/130277124


猜你喜欢
- 为了自定义一个模板标签,你需要告诉Django当遇到你的标签时怎样进行这个过程。当Django编译一个模板时,它将原始模板分成一个个 节点
- 1. 文件注释File -> settings -> Editor -> File and Code Templates
- 首先,我们需要在vue工程中安装video.js相关依赖。npm install --save video.jsnpm install --
- 运行时请在其目录下添加user.txt passwd.txt两文件。否则会报错。程序没有加异常处理。代码比较挫.....#coding:ut
- 起因看到网上的像素图片,感觉蛮有趣的,就打算用python一些PIL类库写一个。实现思路把一张图片分成多个块,每个块的颜色都等于这个色块中颜
- 引言这两天在做微服务上云的事,之前一直是本地运行,后来在服务器搭建了生产环境集群。上云时出现了一些幺蛾子云上的服务都需要身份验证的,没有专用
- 1、现象a.用localhost访问,正常b.用IP地址访问,则出现403错误2、分析a.怀疑是ACL问题,设置Everyone为完全控制,
- 前言在python中, 切片是一个经常会使用到的语法, 不管是元组, 列表还是字符串, 一般语法就是:sequence[ilow:ihigh
- 本篇文章通过使用python实现对计算机摄像头的调用从而实现摄像监控的功能。利用opencv的图像处理功能可以轻松对计算机摄像头的调用实现实
- 上篇文章给大家介绍了Python爬虫实现百度翻译功能过程详解Python爬虫学习之翻译小程序 感兴趣的朋友点击查看。今天给大家介
- 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一种分治的策略,通常称其为分治法(Divide-and-Conq
- 本文实例讲述了Python实现可获取网易页面所有文本信息的网易网络爬虫功能。分享给大家供大家参考,具体如下:#coding=utf-8#--
- 希尔排序希尔排序是一个叫希尔的数学家提出的一种优化版本的插入排序。首先取一个整数d1=n//2,将元素分为d1个组,每组相邻元素之间的距离为
- 函数嵌套,这个名字有点纠结,也许不太好理解。一个比较常见的函数嵌套特例:递归函数,即函数自己嵌套自己。 一直以为在PHP中不能有太多的函数嵌
- 1,建立数据库文件cnbruce.mdb(不设计任何表)建立数据库的代码:<% Option Explicit&
- 在来回切换中英文输入法的时候连按两下shift总是会蹦出来全局搜索框真的很是麻烦,现在是把这个框给禁用掉1.按ctrl+shift+a,弹出
- 如果出现 automation服务器不能创建对象 解决方法:1、如果是Scripting.FileSystemObje
- 本文实例为大家分享了JavaScript实现切换多张图片的具体代码,供大家参考,具体内容如下循环切换图片HTML+CSS+JavaScrip
- 当管理SQL Server内在的帐户和密码时,我们很容易认为这一切都相当的安全。毕竟,你的SQL Server系统被保护在防火墙里,而且还有
- BCP语句的作用:BCP是SQL提供的进行数据传输的实用程序,这种语句提供了非常快的数据导入的方法。(当然7。0也有BCP的替代方法就是DT