Golang协程和Python协程用法上的那些“不一样”

简介: 本文对比了 Python 和 Go 语言中协程的区别,重点分析了调度机制和执行方式的不同。Go 的协程(goroutine)由运行时自动调度,启动后立即执行;而 Python 协程需通过 await 显式调度,依赖事件循环。文中通过代码示例展示了两种协程的实际运行效果。

习惯了Go语言协程的用法,再来学习Python协程的时候,总感觉用起来哪里不太对,越用越不对劲。于是乎,就想研究一下它们到底有哪些区别!

在 Python 和 Go 中,协程的行为确实有一些关键的区别,主要体现在调度机制和代码的执行方式上。

调度机制

Python 的协程是非阻塞的,但需要显式调度,而 Go 的协程由运行时自动调度,不需要显式等待。

1.Go 协程(Goroutine)

Go 的协程(goroutine)是轻量级的线程,由 Go 运行时自动调度。当启动一个 goroutine 时,它会立即开始运行,而主程序会继续执行后续代码,不会等待 goroutine 完成。

package main
import (
    "fmt"
    "time"
)
func myGoroutine() {
    fmt.Println("Goroutine started")
    time.Sleep(2 * time.Second)
    fmt.Println("Goroutine finished")
}
func main() {
    go myGoroutine() // 启动 goroutine
    fmt.Println("Main continues running")
    time.Sleep(3 * time.Second) // 等待一段时间,确保 goroutine 完成
    fmt.Println("Main finished")
}

运行结果:

Main continues running
Goroutine started
Goroutine finished
Main finished

2.Python 协程

Python 的协程需要显式地通过 await(暂停当前协程的执行,等待另一个协程或 Future 完成) 来暂停和恢复执行。当启动一个协程时,它不会立即运行,而是需要被事件循环调度。如果你使用 await,当前协程会暂停,等待被调度的任务完成。

import asyncio
async def my_coroutine():
    print("Coroutine started")
    await asyncio.sleep(2)
    print("Coroutine finished")
async def main():
    task = asyncio.create_task(my_coroutine())  # 启动协程
    print("Task created, continuing execution")
    await asyncio.sleep(1)  # 主程序继续运行
    print("Doing other work")
    await task  # 等待协程完成
    print("Task completed")
asyncio.run(main())

运行结果:

Task created, continuing execution
Doing other work
Coroutine started
Coroutine finished
Task completed

在 Python 中,asyncio.create_task(my_coroutine()) 启动协程后,主程序会继续执行,不会等待协程完成。只有在使用 await task 时,主程序才会暂停,等待协程完成。

相关文章
|
2月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
4月前
|
人工智能 数据库连接 API
掌握Python的高级用法:技巧、技术和实用性示例
本文分享了Python的高级用法,包括生成器、装饰器、上下文管理器、元类和并发编程等。生成器通过`yield`实现懒加载序列;装饰器用于增强函数功能,如添加日志或性能分析;上下文管理器借助`with`语句管理资源;元类动态定制类行为;并发编程利用`threading`和`asyncio`库提升任务执行效率。掌握这些高级概念可优化代码质量,解决复杂问题,提高程序性能与可维护性。
|
5月前
|
Python
Python教程:os 与 sys 模块详细用法
os 模块用于与操作系统交互,主要涉及夹操作、路径操作和其他操作。例如,`os.rename()` 重命名文件,`os.mkdir()` 创建文件夹,`os.path.abspath()` 获取文件绝对路径等。sys 模块则用于与 Python 解释器交互,常用功能如 `sys.path` 查看模块搜索路径,`sys.platform` 检测操作系统等。这些模块提供了丰富的工具,便于开发中处理系统和文件相关任务。
187 14
|
6月前
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
|
6月前
|
SQL Oracle 关系型数据库
【YashanDB知识库】共享利用Python脚本解决Oracle的SQL脚本@@用法
本文来自YashanDB官网,介绍如何处理Oracle客户端sql*plus中使用@@调用同级目录SQL脚本的场景。崖山数据库23.2.x.100已支持@@用法,但旧版本可通过Python脚本批量重写SQL文件,将@@替换为绝对路径。文章通过Oracle示例展示了具体用法,并提供Python脚本实现自动化处理,最后调整批处理脚本以适配YashanDB运行环境。
|
10月前
|
存储 安全 测试技术
GoLang协程Goroutiney原理与GMP模型详解
本文详细介绍了Go语言中的Goroutine及其背后的GMP模型。Goroutine是Go语言中的一种轻量级线程,由Go运行时管理,支持高效的并发编程。文章讲解了Goroutine的创建、调度、上下文切换和栈管理等核心机制,并通过示例代码展示了如何使用Goroutine。GMP模型(Goroutine、Processor、Machine)是Go运行时调度Goroutine的基础,通过合理的调度策略,实现了高并发和高性能的程序执行。
515 29
|
10月前
|
Python
Python三引号用法与变量详解
本文详细介绍了Python中三引号(`"""` 或 `'''`)的用法,包括其基本功能、如何在多行字符串中使用变量(如f-string、str.format()和%操作符),以及实际应用示例,帮助读者更好地理解和运用这一强大工具。
822 2
|
10月前
|
Go 计算机视觉
在Golang高并发环境中如何进行协程同步?
在此示例中,使用互斥锁来保护对共享计数器变量 c 的访问,确保并发的 HTTP 请求不会产生数据竞争。
154 3
|
10月前
|
负载均衡 算法 Go
GoLang协程Goroutiney原理与GMP模型详解
【11月更文挑战第4天】Goroutine 是 Go 语言中的轻量级线程,由 Go 运行时管理,创建和销毁开销小,适合高并发场景。其调度采用非抢占式和协作式多任务处理结合的方式。GMP 模型包括 G(Goroutine)、M(系统线程)和 P(逻辑处理器),通过工作窃取算法实现负载均衡,确保高效利用系统资源。
168 3
|
11月前
|
缓存 测试技术 开发者
深入理解Python装饰器:用法与实现
【10月更文挑战第7天】深入理解Python装饰器:用法与实现
84 1

热门文章

最新文章