goroutine

本文探讨了Go语言中的goroutine概念,它是轻量级线程,内存共享,易于创建和管理。此外,文章介绍了Go的CSP并发模型,强调了通过channel进行通信的重要性。还讨论了goroutine的优点如低内存消耗和小切换成本,以及其缺点如非公平调度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

goroutine

goroutine是Go语言提供的一种用户态线程,有时我们也称之为协程。但是它比线程更小,十几个goroutine可能体现在底层就是五六个线程,Go语言内部实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大概是4~5KB),当然会根据相应的数据伸缩。也正因为如此,可同时运行成千上万个并发任务。goroutine比thread更易用、更高效、更轻便。

线程和协程

  • 进程:拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。
  • 线程:拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度。
  • 协程 :和线程一样共享堆,不共享栈,协程由程序员在协程的代码里显示调度。

创建goroutine

创建goroutine,只需要在函数调用语句前添加go关键字。

但是如果主函数先退出,其他的goroutine也会自动退出。

如果这个函数有返回值,那么这个返回值会被丢弃。

func newTask() {
    fmt.Println("new goroutine")
}

func main() {
    //创建一个 goroutine,启动另外一个任务
    go newTask()

    fmt.Println("main goroutine exit")
}

Go并发模型

Go实现了两种并发形式。

  • 多线程共享内存。其实就是Java或者C++等语言中的多线程开发。
  • CSP(communicating sequential processes)并发模型。这是Go语言特有的,也是Go语言推荐的。

普通的线程并发模型,就是像Java、C++、或者Python,他们线程间通信都是通过共享内存的方式来进行的。非常典型的方式就是,在访问共享数据(例如数组、Map、或者某个结构体或对象)的时候,通过锁来访问。

CSP讲究的是“以通信的方式来共享内存”。

DO NOT COMMUNICATE BY SHARING MEMORY; INSTEAD, SHARE MEMORY BY COMMUNICATING.
“不要以共享内存的方式来通信,相反,要通过通信来共享内存。”

Go的CSP并发模型,是通过goroutinechannel来实现的。

  • goroutine 是Go语言中并发的执行单位。有点抽象,其实就是和传统概念上的”线程“类似,可以理解为”线程“。
  • channel是Go语言中各个并发结构体(goroutine)之前的通信机制。 通俗的讲,就是各个goroutine之间通信的”管道“,有点类似于Linux中的管道。
var ch = make(chan string)

func send() {
	fmt.Println("send data to ch")
	ch <- "test"
}

func recive() {
	result := <-ch
	fmt.Printf("get data from ch: %s", result)
}

func main() {
	go recive()
	go send()
	time.Sleep(5 * time.Second)
}

优点

  • 内存消耗更少:Goroutine所需要的内存通常只有2kb,而线程则需要1Mb
  • 创建与销毁的开销更小:由于线程创建时需要向操作系统申请资源,并且在销毁时将资源归还,因此它的创建和销毁的开销比较大。相比之下,goroutine的创建和销毁是由go语言在运行时自己管理的,因此开销更低。
  • 切换开销更小线程的调度方式是抢占式的,如果一个线程的执行时间超过了分配给它的时间片,就会被其它可执行的线程抢占;而goroutine的调度是协同式的,它不会直接地与操作系统内核打交道。

缺点

  • 协程调度机制无法实现公平调度:因为协程的调度是非入侵式的,系统不会为他分配资源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_李少侠_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值