diff --git a/docs/golang_tutorial_21.md b/docs/golang_tutorial_21.md index c2aee07..cda1f43 100644 --- a/docs/golang_tutorial_21.md +++ b/docs/golang_tutorial_21.md @@ -15,9 +15,9 @@ Go协程(`Goroutine`)是与其他[函数](/docs/golang_tutorial_6.md)或[方 ## Go协程对比线程的优点 -* **与线程相比,Go协程的开销非常小。Go协程的堆栈大小只有几kb,它可以根据应用程序的需要而增长和缩小,而线程必须指定堆栈的大小,并且堆栈的大小是固定的**。 -* **Go协程被多路复用到较少的OS线程。在一个程序中数千个Go协程可能只运行在一个线程中。如果该线程中的任何一个Go协程阻塞(比如等待用户输入),那么Go会创建一个新的OS线程并将其余的Go协程移动到这个新的OS线程。所有这些操作都是 runtime 来完成的,而我们程序员不必关心这些复杂的细节,只需要利用 Go 提供的简洁的 API 来处理并发就可以了。** -* **Go 协程之间通过信道(`channel`)进行通信。信道可以防止多个协程访问共享内存时发生竟险(race condition)。信道可以想象成多个协程之间通信的管道。我们将在下一篇教程中介绍信道。** +* 与线程相比,Go协程的开销非常小。Go协程的堆栈大小只有几kb,它可以根据应用程序的需要而增长和缩小,而线程必须指定堆栈的大小,并且堆栈的大小是固定的。 +* Go协程被多路复用到较少的OS线程。在一个程序中数千个Go协程可能只运行在一个线程中。如果该线程中的任何一个Go协程阻塞(比如等待用户输入),那么Go会创建一个新的OS线程并将其余的Go协程移动到这个新的OS线程。所有这些操作都是 runtime 来完成的,而我们程序员不必关心这些复杂的细节,只需要利用 Go 提供的简洁的 API 来处理并发就可以了。 +* Go 协程之间通过信道(`channel`)进行通信。信道可以防止多个协程访问共享内存时发生竟险(race condition)。信道可以想象成多个协程之间通信的管道。我们将在下一篇教程中介绍信道。 ## 如何创建一个协程? @@ -42,16 +42,16 @@ func main() { 第11行,`go hello()` 开启了一个新的协程。现在 `hello()` 函数将和 `main()` 函数一起运行。`main` 函数在单独的协程中运行,这个协程称为主协程。 -运行这个程序,你将得到一个惊喜。 +运行这个程序,你将得到一个惊喜。程序仅输出了一行文本: `main function`。 -程序仅输出了一行文本: `main function`。 - -我们创建的协程发生了什么?我们需要了解Go协程的两个属性,以了解为什么发生这种情况。 +**我们创建的协程发生了什么?我们需要了解Go协程的两个属性,以了解为什么发生这种情况。** * 当创建一个Go协程时,创建这个Go协程的语句立即返回。与函数不同,程序流程不会等待Go协程结束再继续执行。程序流程在开启Go协程后立即返回并开始执行下一行代码,忽略Go协程的任何返回值。 * 在主协程存在时才能运行其他协程,主协程终止则程序终止,其他协程也将终止。 -我想你已经知道了为什么我们的协程为什么没有运行。在11行调用 `go hello()`后,程序的流程直接调转到下一条语句执行,并没有等待 `hello` 协程退出,然后打印 `main function`。接着主协程结束运行,不会再执行任何代码,因此 `hello` 协程没有得到运行的机会。 +我想你已经知道了为什么我们的协程为什么没有运行。在11行调用 `go hello()`后,程序的流程直接调转到下一条语句执行,并没有等待 `hello` 协程退出,然后打印 `main function`。 + +接着主协程结束运行,不会再执行任何代码,因此 `hello` 协程没有得到运行的机会。 让我们修复这个问题: