Golang入门:协程(goroutine)
goroutine
goroutine 是 Go 的并发模型的核心概念。为了理解 goroutine,我们来定义几个术语。第一个是进程。进程是程序的实例,由计算机的操作系统运行。操作系统将一些资源(如内存)与进程相关联,并确保其他进程不能访问它们。进程由一个或多个线程组成。一个线程是一个执行单元,由操作系统运行。一个进程中的线程共享对资源的访问。一个 CPU 可以同时执行多少个线程的指令取决于内核的数量。操作系统的工作之一是在 CPU 上调度线程,以确保每个进程(以及进程中的每个线程)都有机会运行。
goroutine 是由 Go 运行时管理的轻量级进程。当 Go 程序启动时,Go 运行时会创建一些线程并启动一个 goroutine 来运行程序。你的程序创建的所有 goroutine(包括程序入口部分)都由 Go 运行时调度器自动分配给这些线程,就像操作系统在 CPU 内核间调度线程一样。这似乎看起来是额外的工作,因为底层操作系统已经包含了一个管理线程和进程的调度器,但 goroutine 有几个好处:
1. 创建 goroutine 比创建线程更快,因为你不是在创建操作系统级的资源。
2. goroutine 的初始栈比线程栈更小,并且可以根据需要增长。这使得 goroutine 的内存效率更高。
3. 在 goroutine 之间切换比在线程之间切换更快,因为 goroutine 之间的切换完全发生在进程内部,避免了操作系统(相对)缓慢的调用。
4. 调度器作为 Go 进程的一部分能够进行优化。当调度器与网络轮询器一起工作时,可以检测 goroutine 何时因为 I/O 阻塞而无法调度。它还与垃圾回收器集成,确保工作在所有操作系统线程之间可以较为平均地分配给 Go 进程。
这些优势使得 Go 程序可以同时生成数百、数千甚至数万个 goroutine。如果你尝试在一种使用本地线程的语言中启动成千上万个线程,程序就会慢到如同乌龟在爬行。
如果你有兴趣了解关于调度器的更多知识,可以听一下 Kavya Joshi在GopherCon 2018上发表的名为“The Scheduler Saga”的演讲(https://oreil.ly/879mk)。
在一个函数调用前放置 go 关键字可以启动一个 goroutine。与其他函数一样,我们可以向它传递参数以初始化其状态。不过,任何函数返回的值都会被忽略。
任何函数都可以作为 goroutine 启动。这与 JavaScript 不同,在 JavaScript 中,只有当使用 async 关键字声明函数时,函数才会异步运行。然而,在 Go 中,大家习惯于用一个封装业务逻辑的闭包来启动 goroutine。该闭包负责管理并发的数据和状态。例如,闭包从通道中读取数值并将其传递给业务逻辑,业务逻辑完全不知道它是在一个 goroutine 中运行的。然后,函数的结果被写回另一个通道。这种职责分离使代码模块化、可测试,并使 API 调用简单,无须关注并发问题:
func process(val int) int {
// do something with val
}
func runTingConcurrently(in <-chan int, out chan<- int) {
go func() {
for val := range in {
result := process(val)
out <- result
}
}()
}
Golang入门:协程(goroutine)的更多相关文章
- GoLang之协程
GoLang之协程 目前,WebServer几种主流的并发模型: 多线程,每个线程一次处理一个请求,在当前请求处理完成之前不会接收其它请求:但在高并发环境下,多线程的开销比较大: 基于回调的异步IO, ...
- Golang 之协程详解
转自:https://www.cnblogs.com/liang1101/p/7285955.html 一.Golang 线程和协程的区别 备注:需要区分进程.线程(内核级线程).协程(用户级线程)三 ...
- Golang 的 协程调度机制 与 GOMAXPROCS 性能调优
作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...
- GoLang 的协程调度和 GMP 模型
GoLang 的协程调度和 GMP 模型 GoLang 是怎么启动的 关于 GoLang 的汇编语言,请查阅 参考文献[1] 和 参考文献[2] 编写一个简单的 GoLang 程序 main.go, ...
- 在C++中使用golang的协程
开源项目cpp_features提供了一个仿golang协程的stackful协程库. 可以在c++中使用golang的协程,大概语法是这样的: #include <iostream> v ...
- 一个有趣的小例子,带你入门协程模块-asyncio
一个有趣的小例子,带你入门协程模块-asyncio 上篇文章写了关于yield from的用法,简单的了解异步模式,[https://www.cnblogs.com/c-x-a/p/10106031. ...
- 『GoLang』协程与通道
作为一门 21 世纪的语言,Go 原生支持应用之间的通信(网络,客户端和服务端,分布式计算)和程序的并发.程序可以在不同的处理器和计算机上同时执行不同的代码段.Go 语言为构建并发程序的基本代码块是 ...
- [golang note] 协程基础
协程概念 √ 协程通常称为coroutine,在golang中称为goroutine. √ 协程本质上是一种用户态线程,它不需要操作系统来进行抢占式调度,在实际实现中寄存在线程之中. √ 协程系统开销 ...
- golang:协程安全
多路复用 Go语言中提供了一个关键字select,通过select可以监听channel上的数据流动.select的用法与switch语法类似,由select开始一个新的选择块,每个选择条件由case ...
- [Golang]-5 协程、通道及其缓冲、同步、方向和选择器
目录 协程 通道 通道缓冲 通道同步 通道方向 通道选择器 协程 Go 协程 在执行上来说是轻量级的线程. 代码演示 import ( "fmt" "time" ...
随机推荐
- [转]CMake与Make最简单直接的区别
写程序大体步骤为: 1.用编辑器编写源代码,如.c文件. 2.用编译器编译代码生成目标文件,如.o. 3.用链接器连接目标代码生成可执行文件,如.exe. 但如果源文件太多,一个一个编译时就会特别麻烦 ...
- UdpClient.BeginReceive(AsyncCallback, Object) 方法
命名空间: System.Net.Sockets 程序集: System.Net.Sockets.dll 从远程主机异步接收数据报. public IAsyncResult BeginReceive ...
- JVM实战—4.JVM垃圾回收器的原理和调优
大纲 1.JVM的新生代垃圾回收器ParNew如何工作 2.JVM老年代垃圾回收器CMS是如何工作的 3.线上部署系统时如何设置垃圾回收相关参数 4.新生代垃圾回收参数如何优化 5.老年代的垃圾回收参 ...
- 掌握 PostgreSQL 的 psql 命令行工具
title: 掌握 PostgreSQL 的 psql 命令行工具 date: 2024/12/30 updated: 2024/12/30 author: cmdragon excerpt: psq ...
- SQL优化——深分页&排序
问题背景 在开发 Web 应用或处理数据库查询时,分页是一项常见需求.然而,当面对深度分页(即页码较大,偏移量较高的分页情况)时,性能问题往往接踵而至.比如对一些需要拉特定的页面查询.范围导出.范围计 ...
- Solution Set - “女孩是瑰宝我心动一丝不苟”
目录 0.「NOI Simu.」静态顶树 1.「NOI Simu.」祖先 2.「NOI Simu.」睡眠 3.「JLOI 2008」「洛谷 P3881」CODES 4.「ARC 163A」Divide ...
- Solution Set -「NOIP Simu.」20221008
\(\mathscr{A}\sim\)「CF 1680E」Moving Chips Link & Submission. Tag:「水题无 tag」 温暖签到惹, DP 一下就好了 ...
- HashMap的put方法的扩容流程
final Node<K,V>[] resize() { // [1,2,3,4,5,6,7,8,9,10,11,,,,] Node<K,V>[] oldTab = table ...
- 为什么UNIX使用init进程启动其他进程?
为什么UNIX使用init进程启动其他进程? 在UNIX系统中,当系统启动时,内核完成初始化后会启动第一个用户空间进程,通常是init进程.init进程负责启动和管理其他用户空间进程,而内核本身并不直 ...
- Windows中通过NVM安装和切换各个NodeJS版本
1.下载nvm 下载地址:https://github.com/coreybutler/nvm-windows/releases 如我们下载:https://github.com/coreybutle ...