Goroutines and Parallelism

Go 语言层面支持的go 关键字,可以快速的让一个函数创建为 goroutine, 我们可以认为main 函数就是作为 goroutine 执行的。操作系统调度线程在可用处理器上运行,Go 运行时调度 goroutine 在绑定到单个操作系统线程的逻辑处理器中运行(P)。即使使用这个单一的逻辑处理器和操作系统线程,也可以调度数十万 goroutine 以惊人的效率和性能并发运行。

Concurrency is not Parallelism

并发不是并行。并行是指两个或多个线程同时在不同的处理器执行代码。如果将运行时配置为使用多个逻辑处理器,则调度程序将在这些逻辑处理器之间分配 goroutine,这将导致 goroutine 在不同的操作系统线程上运行。但是,要获得真正的并行性,您需要在具有多个物理处理器的计算机上运行程序。否则,goroutine 将针对单个物理处理器并发运行,即使 Go运行时使用多个逻辑处理器。

Any time you start a Goroutine you must ask yourself:

  • When will it terminate?
  • What could prevent it from terminating?

看个例子:

这个简单的应用程序在两个不同的端口上提供http 流量,端口8080用于应用程序流量, 端口8001用于访问 ldebug/pprof 端点。

image-20230830090203035

通过将 serveApp 和 serveDebug处理程序分解为各自的函数,我们将它们与 main.main 解耦,我们还遵循了上面的建议,并确保 serveApp 和 serveDebug 将它们的并发性留给调用者。如果 serveApp返回,则main.main 将返回导致程序关闭,只能靠类似 supervisor 进程管理来重新启动。

image-20230830090213975

然而,serveDebug 是在一个单独的 goroutine 中运行的,如果它返回,那么所在的 goroutine 将退出,而程序的其余部分继续运行。由于/debug 处理程序很久以前就停止工作了,所以其他同学会很不高兴地发现他们无法在需要时从您的应用程序中获取统计信息。

image-20230830090253418

Never start a goroutine without knowning when it wil stop

image-20230830090441381

image-20230830090502461

最后修改:2023 年 08 月 31 日
如果觉得我的文章对你有用,请随意赞赏