Compare commits

..

No commits in common. "1597ed7bcd228dd4c8bf769e72bd32eebb6d19ba" and "561b2d100aefbb1cc48613972a84f2399fb27caa" have entirely different histories.

3 changed files with 5 additions and 5 deletions

View File

@ -71,7 +71,7 @@ s[0] = 'L' // compile error: cannot assign to s[0]
字符串值也可以用字符串面值方式编写,只要将一系列字节序列包含在双引号内即可: 字符串值也可以用字符串面值方式编写,只要将一系列字节序列包含在双引号内即可:
``` ```
"Hello, world" "Hello, 世界"
``` ```
![](../images/ch3-04.png) ![](../images/ch3-04.png)

View File

@ -17,7 +17,7 @@ func Parse(input string) (s *Syntax, err error) {
} }
``` ```
recover函数帮助Parse从panic中恢复。在deferred函数内部panic value被附加到错误信息中并用err变量接收错误信息返回给调用者。我们也可以通过调用runtime.Stack往错误信息中添加完整的堆栈调用信息。 deferred函数帮助Parse从panic中恢复。在deferred函数内部panic value被附加到错误信息中并用err变量接收错误信息返回给调用者。我们也可以通过调用runtime.Stack往错误信息中添加完整的堆栈调用信息。
不加区分的恢复所有的panic异常不是可取的做法因为在panic之后无法保证包级变量的状态仍然和我们预期一致。比如对数据结构的一次重要更新没有被完整完成、文件或者网络连接没有被关闭、获得的锁没有被释放。此外如果写日志时产生的panic被不加区分的恢复可能会导致漏洞被忽略。 不加区分的恢复所有的panic异常不是可取的做法因为在panic之后无法保证包级变量的状态仍然和我们预期一致。比如对数据结构的一次重要更新没有被完整完成、文件或者网络连接没有被关闭、获得的锁没有被释放。此外如果写日志时产生的panic被不加区分的恢复可能会导致漏洞被忽略。

View File

@ -8,7 +8,7 @@
相反一个goroutine会以一个很小的栈开始其生命周期一般只需要2KB。一个goroutine的栈和操作系统线程一样会保存其活跃或挂起的函数调用的本地变量但是和OS线程不太一样的是一个goroutine的栈大小并不是固定的栈的大小会根据需要动态地伸缩。而goroutine的栈的最大值有1GB比传统的固定大小的线程栈要大得多尽管一般情况下大多goroutine都不需要这么大的栈。 相反一个goroutine会以一个很小的栈开始其生命周期一般只需要2KB。一个goroutine的栈和操作系统线程一样会保存其活跃或挂起的函数调用的本地变量但是和OS线程不太一样的是一个goroutine的栈大小并不是固定的栈的大小会根据需要动态地伸缩。而goroutine的栈的最大值有1GB比传统的固定大小的线程栈要大得多尽管一般情况下大多goroutine都不需要这么大的栈。
**练习 9.4:** 创建一个流水线程序支持用channel连接任意数量的goroutine在跑爆内存之前可以创建多少流水线阶段一个变量通过整个流水线需要用多久这个练习题翻译不是很确定 ** 练习 9.4:** 创建一个流水线程序支持用channel连接任意数量的goroutine在跑爆内存之前可以创建多少流水线阶段一个变量通过整个流水线需要用多久这个练习题翻译不是很确定
### 9.8.2. Goroutine调度 ### 9.8.2. Goroutine调度
@ -18,7 +18,7 @@ Go的运行时包含了其自己的调度器这个调度器使用了一些技
和操作系统的线程调度不同的是Go调度器并不是用一个硬件定时器而是被Go语言“建筑”本身进行调度的。例如当一个goroutine调用了time.Sleep或者被channel调用或者mutex操作阻塞时调度器会使其进入休眠并开始执行另一个goroutine直到时机到了再去唤醒第一个goroutine。因为这种调度方式不需要进入内核的上下文所以重新调度一个goroutine比调度一个线程代价要低得多。 和操作系统的线程调度不同的是Go调度器并不是用一个硬件定时器而是被Go语言“建筑”本身进行调度的。例如当一个goroutine调用了time.Sleep或者被channel调用或者mutex操作阻塞时调度器会使其进入休眠并开始执行另一个goroutine直到时机到了再去唤醒第一个goroutine。因为这种调度方式不需要进入内核的上下文所以重新调度一个goroutine比调度一个线程代价要低得多。
**练习 9.5:** 写一个有两个goroutine的程序两个goroutine会向两个无buffer channel反复地发送ping-pong消息。这样的程序每秒可以支持多少次通信 ** 练习 9.5: ** 写一个有两个goroutine的程序两个goroutine会向两个无buffer channel反复地发送ping-pong消息。这样的程序每秒可以支持多少次通信
### 9.8.3. GOMAXPROCS ### 9.8.3. GOMAXPROCS
@ -42,7 +42,7 @@ $ GOMAXPROCS=2 go run hacker-cliché.go
在第一次执行时最多同时只能有一个goroutine被执行。初始情况下只有main goroutine被执行所以会打印很多1。过了一段时间后GO调度器会将其置为休眠并唤醒另一个goroutine这时候就开始打印很多0了在打印的时候goroutine是被调度到操作系统线程上的。在第二次执行时我们使用了两个操作系统线程所以两个goroutine可以一起被执行以同样的频率交替打印0和1。我们必须强调的是goroutine的调度是受很多因子影响的而runtime也是在不断地发展演进的所以这里的你实际得到的结果可能会因为版本的不同而与我们运行的结果有所不同。 在第一次执行时最多同时只能有一个goroutine被执行。初始情况下只有main goroutine被执行所以会打印很多1。过了一段时间后GO调度器会将其置为休眠并唤醒另一个goroutine这时候就开始打印很多0了在打印的时候goroutine是被调度到操作系统线程上的。在第二次执行时我们使用了两个操作系统线程所以两个goroutine可以一起被执行以同样的频率交替打印0和1。我们必须强调的是goroutine的调度是受很多因子影响的而runtime也是在不断地发展演进的所以这里的你实际得到的结果可能会因为版本的不同而与我们运行的结果有所不同。
**练习9.6:** 测试一下计算密集型的并发程序练习8.5那样的会被GOMAXPROCS怎样影响到。在你的电脑上最佳的值是多少你的电脑CPU有多少个核心 ** 练习9.6:** 测试一下计算密集型的并发程序练习8.5那样的会被GOMAXPROCS怎样影响到。在你的电脑上最佳的值是多少你的电脑CPU有多少个核心
### 9.8.4. Goroutine没有ID号 ### 9.8.4. Goroutine没有ID号