完成14.1

This commit is contained in:
glight2000
2015-12-24 12:13:07 +08:00
parent 6e04c75a94
commit 33b3655ccc

View File

@@ -76,10 +76,78 @@ runtime.GOMAXPROCS(*numCores)
示例 14.1-[goroutine1.go](examples/chapter_14/goroutine1.go) 介绍了概念:
```go
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("In main()")
go longWait()
go shortWait()
fmt.Println("About to sleep in main()")
// sleep works with a Duration in nanoseconds (ns) !
time.Sleep(10 * 1e9)
fmt.Println("At the end of main()")
}
func longWait() {
fmt.Println("Beginning longWait()")
time.Sleep(5 * 1e9) // sleep for 5 seconds
fmt.Println("End of longWait()")
}
func shortWait() {
fmt.Println("Beginning shortWait()")
time.Sleep(2 * 1e9) // sleep for 2 seconds
fmt.Println("End of shortWait()")
}
```
输出
```
In main()
About to sleep in main()
Beginning longWait()
Beginning shortWait()
End of shortWait()
End of longWait()
At the end of main() // after 10s
```
`main()``longWait()``shortWait()`三个函数作为独立的处理单元按顺序启动,然后开始并行运行。每一个函数都在运行的开始和结束阶段输出了消息。为了模拟他们运算的时间消耗,我们使用了`time`包中的`Sleep`函数。`Sleep()`可以按照指定的时间来暂停函数或协程的执行这里使用了纳秒ns符号1e9表示1乘10的9次方e=指数)。
他们按照我们期望的顺序打印出了消息,几乎都一样,可是我们明白这是模拟出来的,以并行的方式。我们让`main()`函数暂停10秒从而确定它会在另外两个协程之后结束。如果不这样如果我们让`main()`函数停止4秒`main()`会提前结束,`longWait()`则无法完成。如果我们不在`main()`中等待,协程会随着程序的结束而消亡。
`main()`函数返回的时候程序退出它不会等待任何其他非main协程的结束。这就是为什么在服务器程序中每一个请求都会启动一个协程来处理`server()`函数必须保持运行状态。通常使用一个无限循环来达到这样的目的。
另外,协程是独立的处理单元,一旦陆续启动一些协程,你无法确定他们是什么时候真正开始执行的。你的代码罗技必须具独立于协程调用的顺序。
为了对比使用一个线程连续调用的情况移除go关键字重新运行程序。
现在输出:
```
In main()
Beginning longWait()
End of longWait()
Beginning shortWait()
End of shortWait()
About to sleep in main()
At the end of main() // after 17 s
```
协程更有用的一个例子应该是在一个非常长的数组中查找一个元素。
将数组分割为若干个不重复的切片,然后给每一个切片启动一个协程进行查找计算。这样许多并行的线程可以用来进行查找任务,整体的查找时间会缩短(除以协程的数量)。
## 14.1.5 Go协程goroutines和协程coroutines
译者注标题中的“Go协程goroutines”即是14章讲的协程指的是go语言中的协程。而“协程coroutines”指的是其他语言中的协程概念仅在本节出现。
在其他语言中比如C#Lua或者Python都有协程的概念。这个名字表明它和Go协程有些相似不过有两点不同
* go协程意味着并行或者可以以并行的方式部署协程一般来说不是这样的
* go协程通过通道来通信协程通过让出和恢复操作来通信
Go协程比协程更强大也很容易从协程的逻辑复用到go协程。
## 链接