golang中协程是goroutine,不同的是,Golang在runtime、系统调用等多方面对goroutine调度进行了封装和处理,当遇到长时间执行或者进行系统调用时,会主动把当前goroutine的CPU转让出去,让其他goroutine能被调度并执行,Golang从语言层面原生支持协程,在函数或者方法前面加go关键字就可创建一个协程。
本教程操作环境:windows10系统、go1.20.1版本、Dell G3电脑。
对于协程(用户级线程),这是对内核透明的,也就是系统并不知道有协程的存在,完全由驴自己的程序进行调度的,因为是由用户程序自己控制,那么就很难像抢占式调度那样做到强制的CPU控制权切换到其他进程/线程,通常只能进行协作式调度,需要协程自己主动把控制权转让出去之后,其他协程才能被执行到。
go-routine和协程区别
本质上, goroutine 就是协程。不同的是,Golang 在runtime、系统调用等多方面对goroutine调度进行了封装和处理,当遇到长时间执行或者进行系统调用时,会主动把当前goroutine的CPU (P)转让出去,让其他goroutine能被调度并执行,也就是Golang从语言层面支持了协程。Golang 的一大特色就是从语言层面原生支持协程,在函数或者方法前面加go关键字就可创建一个协程。
其他方面的比较
1、内存消耗方面
每个go-routine (协程)默认占用内存远比Java、C的线程少。
go-routine. 2KB。
线程: 8MB。
2、线程和go-routine切换调度开销方面
线程/go-routine切换开销方面,go-routine 远比线程小。
线程:涉及模式切换(从用户态切换到内核态)、16个寄存器、PC、 SP.. 等寄存器的刷新等。
go-routine:只有三个寄存器的值修改- PC/SP /DX。
二、协程底层实现原理
线程是操作系统的内核对象,多线程编程时,如果线程数过多,就会导致频繁的上下文切换,这些cpu时间是一个额外的耗费。 所以在一些高并发的网络服务器编程中,使用一个线程服务-个socket连接是很不明智的。于是操作系统提供了基于事件模式的异步编程模型。用少量的线程来服务大量的网络连接和/0操作。但是采用异步和基于事件的编程模型,复杂化了程序代码的编写,非常容易出错。因为线程穿插,也提高排查错误的难度。
协程,是在应用层模拟的线程,他避免了上下文切换的额外耗费,兼顾了多线程的优点。简化了高并发程序的复杂度。举个例子,一个高并发的网络服务器,每一个socket连接进来, 服务器用一个协程来对他进行服务。代码非常清晰。而且兼顾了性能。
以上是golang中协程是什么的详细内容。更多信息请关注PHP中文网其他相关文章!