6.1 go协程

go协程类似一个线程,但是go协程是由go自己调度,而不是系统。在协程中的代码可以和其他代码并发执行。让我们看一个例子:

package main

import (
    "fmt"
    "time"
)

func main() {
    fmt.Println("start")
    go process()
    time.Sleep(time.Millisecond * 10) // this is bad, don't do this!
    fmt.Println("done")
}

func process() {
    fmt.Println("processing")
}

这个例子有一些有趣的事,但是最重要的是了解我们是如何启动一个go协程。我们只是简单的将go关键字附在我们想要执行的函数前面即可。如果我们只想执行一小段代码,例如上面的例子一样,我们可以使用一个匿名函数。需要注意的是,匿名函数不只是在go协程中使用,其他地方也可以。

go func() {
    fmt.Println("processing")
}()

go协程很容易创建且开销较小。最终多个go协程将会在同一个底层的系统线程上运行。这也常称之为M:N线程模型,因为我们有M个应用线程(go协程)运行在N个系统线程上。结果就是,一个go协程的开销和系统线程比起来相对很低(一般都是几KB)。在现代的硬件上,有可能拥有成千上万个go协程。

另外,这里还隐藏了映射和调度的复杂性。我们只需要说这段代码需要并发执行,然后让go自己去处理。

如果我们回到刚刚的例子中,你将会注意到我们使用了Sleep让程序等待了几毫秒。这是因为主进程在退出前协程才有机会去执行(主进程在退出前不会等待所有协程都执行完毕)。为了解决这个问题,我们必须让代码协同。

链接

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「IT平头哥联盟」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

results matching ""

    No results matching ""