1
0
mirror of https://github.com/chai2010/advanced-go-programming-book.git synced 2025-05-23 20:02:22 +00:00

ch1-05 优化排版

This commit is contained in:
iGmainC 2022-01-17 14:38:42 +08:00
parent 9134b28201
commit b4b823a6c9

View File

@ -2,7 +2,7 @@
在早期CPU 都是以单核的形式顺序执行机器指令。Go 语言的祖先 C 语言正是这种顺序编程语言的代表。顺序编程语言中的顺序是指:所有的指令都是以串行的方式执行,在相同的时刻有且仅有一个 CPU 在顺序执行程序的指令。
随着处理器技术的发展,单核时代以提升处理器频率来提高运行效率的方式遇到了瓶颈,目前各种主流的CPU频率基本被锁定在了3GHZ附近。单核CPU的发展的停滞给多核CPU的发展带来了机遇。相应地编程语言也开始逐步向并行化的方向发展。Go语言正是在多核和网络化的时代背景下诞生的原生支持并发的编程语言。
随着处理器技术的发展,单核时代以提升处理器频率来提高运行效率的方式遇到了瓶颈,目前各种主流的 CPU 频率基本被锁定在了 3Ghz 附近。单核 CPU 的发展的停滞,给多核 CPU 的发展带来了机遇。相应地编程语言也开始逐步向并行化的方向发展。Go 语言正是在多核和网络化的时代背景下诞生的原生支持并发的编程语言。
常见的并行编程有多种模型主要有多线程、消息传递等。从理论上来看多线程和基于消息的并发编程是等价的。由于多线程并发模型可以自然对应到多核的处理器主流的操作系统因此也都提供了系统级的多线程支持同时从概念上讲多线程似乎也更直观因此多线程编程模型逐步被吸纳到主流的编程语言特性或语言扩展库中。而主流编程语言对基于消息的并发编程模型支持则相比较少Erlang 语言是支持基于消息传递并发编程模型的代表者它的并发体之间不共享内存。Go 语言是基于消息并发模型的集大成者,它将基于 CSP 模型的并发编程内置到了语言中,通过一个 go 关键字就可以轻易地启动一个 Goroutine与 Erlang 不同的是 Go 语言的 Goroutine 之间是共享内存的。
@ -209,7 +209,6 @@ func main() {
因此,如果在一个 Goroutine 中顺序执行 `a = 1; b = 2;` 两个语句,虽然在当前的 Goroutine 中可以认为 `a = 1;` 语句先于 `b = 2;` 语句执行,但是在另一个 Goroutine 中 `b = 2;` 语句可能会先于 `a = 1;` 语句执行,甚至在另一个 Goroutine 中无法看到它们的变化(可能始终在寄存器中)。也就是说在另一个 Goroutine 看来, `a = 1; b = 2;`两个语句的执行顺序是不确定的。如果一个并发程序无法确定事件的顺序关系,那么程序的运行结果往往会有不确定的结果。比如下面这个程序:
```go
func main() {
go println("你好, 世界")
@ -269,8 +268,7 @@ Go程序的初始化和执行总是从`main.main`函数开始的。但是如果`
## 1.5.5 Goroutine的创建
`go`语句会在当前Goroutine对应函数返回前创建新的Goroutine. 例如:
`go` 语句会在当前 Goroutine 对应函数返回前创建新的 Goroutine。例如:
```go
var a string
@ -289,8 +287,7 @@ func hello() {
## 1.5.6 基于 Channel 的通信
Channel通信是在Goroutine之间进行同步的主要方法。在无缓存的Channel上的每一次发送操作都有与其对应的接收操作相配对发送和接收操作通常发生在不同的Goroutine上在同一个Goroutine上执行2个操作很容易导致死锁。**无缓存的Channel上的发送操作总在对应的接收操作完成前发生.**
Channel 通信是在 Goroutine 之间进行同步的主要方法。在无缓存的 Channel 上的每一次发送操作都有与其对应的接收操作相配对,发送和接收操作通常发生在不同的 Goroutine 上(在同一个 Goroutine 上执行两个操作很容易导致死锁)。**无缓存的 Channel 上的发送操作总在对应的接收操作完成前发生.**
```go
var done = make(chan bool)