返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

9.1 任务

发布于 2024-10-12 19:15:49 字数 1052 浏览 0 评论 0 收藏 0

简单将 goroutine 归为协程(coroutine)并不合适。它类似多线程和协程的综合体,最大限度发挥多核处理能力,提升执行效率。

  • 按需扩张的极小初始栈,支持海量任务。
  • 高效无锁内存分配和复用,提升并发性能。
  • 调度器平衡任务队列,充分利用多处理器。
  • 线程自动休眠和唤醒,减少内核开销。
  • 基于信号(signal)实现抢占式任务调度。

更多实现细节,请阅读下卷《源码剖析》。

关键字 go 将目标函数和参数 打包 (非执行)成并发任务单元,放入待运行队列。

无法确定执行时间、执行次序,以及执行线程,由调度器负责处理。

func main() {
    
    // 打包并发任务(函数 + 参数)。
    // 并非立即执行。
    
	go println("abc")
	go func(x int) { println(x) }(123)

    // 上述并发任务会被其他饥饿线程取走。
    // 执行时间未知,下面这行可能先输出。
    
	println("main")
	time.Sleep(time.Second)
}

参数立即计算并复制。

var c int

func inc() int {
	c++
	return c
}

func main() {
	a := 100

    // 立即计算出参数 (100, 1),并复制。
    // 内部 sleep 目的是让 main 先输出。
    
	go func(x, y int) {
		time.Sleep(time.Second)
		println("go:", x, y)     // 100, 1
	}(a, inc())            

	a += 100                   
	println("main:", a, inc())   // 200, 2

	time.Sleep(time.Second * 3)
}

// main: 200 2
//   go: 100 1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文