File tree Expand file tree Collapse file tree 5 files changed +79
-21
lines changed
Expand file tree Collapse file tree 5 files changed +79
-21
lines changed Original file line number Diff line number Diff line change 4343- 4.6 [ 学习 Go 协程:互斥锁和读写锁] ( http://golang.iswbm.com/en/latest/c04/c04_06.html )
4444- 4.8 [ 学习一些常见的并发模型] ( http://golang.iswbm.com/en/latest/c04/c04_08.html )
4545- 4.9 [ 理解 Go 语言中的 Context] ( http://golang.iswbm.com/en/latest/c04/c04_09.html )
46- - 4.10 [ 函数式编程 ] ( http://golang.iswbm.com/en/latest/c04/c04_10.html )
46+ - 4.10 [ 如何实现一个协程池? ] ( http://golang.iswbm.com/en/latest/c04/c04_10.html )
4747
4848## 第五章:Web实战
4949- 5.1 [ Gin 实战:Hello World] ( http://golang.iswbm.com/en/latest/c05/c05_01.html )
Original file line number Diff line number Diff line change 22
33## 1. 什么是 Context?
44
5- 在 go 1.7 版本之前,context 还是非编制的,它存在于 golang.org/x/net/context 包中。
5+ 在 Go 1.7 版本之前,context 还是非编制的,它存在于 golang.org/x/net/context 包中。
66
7- 后来,golang 团队发现 context 还挺好用的,就把 context 收编了,在 go 1.7 版本正式纳入了标准库。
7+ 后来,Golang 团队发现 context 还挺好用的,就把 context 收编了,在 Go 1.7 版本正式纳入了标准库。
88
99Context,也叫上下文,它的接口定义如下
1010
@@ -74,7 +74,7 @@ func main() {
7474
7575> chan+select的方式,是比较优雅的结束一个goroutine的方式,不过这种方式也有局限性,如果有很多goroutine都需要控制结束怎么办呢?如果这些goroutine又衍生了其他更多的goroutine怎么办呢?如果一层层的无穷尽的goroutine呢?这就非常复杂了,即使我们定义很多chan也很难解决这个问题,因为goroutine的关系链就导致了这种场景非常复杂。
7676
77- 在这里我不是很赞同他说的话,因为我觉得就算只使用一个通道也能控制 (取消)多个 goroutine 的目的。下面就用例子来验证一下。
77+ 在这里我不是很赞同他说的话,因为我觉得就算只使用一个通道也能达到控制 (取消)多个 goroutine 的目的。下面就用例子来验证一下。
7878
7979该例子的原理是:使用 close 关闭通道后,如果该通道是无缓冲的,则它会从原来的阻塞变成非阻塞,也就是可读的,只不过读到的会一直是零值,因此根据这个特性就可以判断 拥有该通道的 goroutine 是否要关闭。
8080
@@ -235,7 +235,7 @@ cancel()
235235
236236创建 Context 必须要指定一个 父 Context,当我们要创建第一个Context时该怎么办呢?
237237
238- 不用担心,Go 已经帮我们实现了2个,我们代码中最开始都是以这两个内置的作为最顶层的partent context,衍生出更多的子Context。
238+ 不用担心,Go 已经帮我们实现了2个,我们代码中最开始都是以这两个内置的context作为最顶层的parent context,衍生出更多的子Context。
239239
240240``` go
241241var (
Original file line number Diff line number Diff line change 441. 什么是 Context?
55-------------------
66
7- 在 go 1.7 版本之前,context 还是非编制的,它存在于
7+ 在 Go 1.7 版本之前,context 还是非编制的,它存在于
88golang.org/x/net/context 包中。
99
10- 后来,golang 团队发现 context 还挺好用的,就把 context 收编了,在 go 1.7
10+ 后来,Golang 团队发现 context 还挺好用的,就把 context 收编了,在 Go 1.7
1111版本正式纳入了标准库。
1212
1313Context,也叫上下文,它的接口定义如下
@@ -87,7 +87,7 @@ Context,也叫上下文,它的接口定义如下
8787
8888 chan+select的方式,是比较优雅的结束一个goroutine的方式,不过这种方式也有局限性,如果有很多goroutine都需要控制结束怎么办呢?如果这些goroutine又衍生了其他更多的goroutine怎么办呢?如果一层层的无穷尽的goroutine呢?这就非常复杂了,即使我们定义很多chan也很难解决这个问题,因为goroutine的关系链就导致了这种场景非常复杂。
8989
90- 在这里我不是很赞同他说的话,因为我觉得就算只使用一个通道也能控制 (取消)多个
90+ 在这里我不是很赞同他说的话,因为我觉得就算只使用一个通道也能达到控制 (取消)多个
9191goroutine 的目的。下面就用例子来验证一下。
9292
9393该例子的原理是:使用 close
@@ -261,7 +261,7 @@ cancel 就是我们在创建 ctx 的时候返回的第二个值。
261261Context,当我们要创建第一个Context时该怎么办呢?
262262
263263不用担心,Go
264- 已经帮我们实现了2个,我们代码中最开始都是以这两个内置的作为最顶层的partent
264+ 已经帮我们实现了2个,我们代码中最开始都是以这两个内置的context作为最顶层的parent
265265context,衍生出更多的子Context。
266266
267267.. code :: go
Original file line number Diff line number Diff line change 1- # 4.10 函数式编程
1+ # 4.10 如何实现一个协程池?
22
3- 函数是一等公民,它可以做为参数进行传递,可以做为函数返回值,也可以做为接收者。所以后来才有了高阶函数,闭包。
3+ 协程池的实现
44
5+ ``` go
6+ type Pool struct {
7+ work chan func () // 任务 sem chan struct{} // 数量
8+ }
9+ func New (size int ) *Pool {
10+ return &Pool{
11+ work: make (chan func ()),
12+ sem: make (chan struct {}, size),
13+ }
14+ }
15+ func (p *Pool ) Schedule (task func()) error { // 任务调度
16+ select {
17+ case p.work <- task:
18+ case p.sem <- struct {}{}:
19+ go p.worker (task)
20+ }
21+ }
22+ func (p *Pool ) worker (task func()) { // 任务执行
23+ defer func () { <- p.sem }
24+ for {
25+ task ()
26+ task = <- p.work
27+ }
28+ }
529
30+ ```
631
7- 正统的函数式编程
8-
9- - 不可变性:不能有状态,只能有函数和变量
10- - 函数只能有一个参数
32+ 协程池的调用
1133
34+ ``` go
35+ pool := gopool.New (128 )
36+ pool.Schedule (func (){
37+ fmt.println (" task run" )
38+ })
39+ ```
1240
Original file line number Diff line number Diff line change 1- 4.10 函数式编程
2- ===============
1+ 4.10 如何实现一个协程池?
2+ =========================
33
4- 函数是一等公民,它可以做为参数进行传递,可以做为函数返回值,也可以做为接收者。所以后来才有了高阶函数,闭包。
4+ 协程池的实现
55
6- 正统的函数式编程
6+ .. code :: go
77
8- - 不可变性:不能有状态,只能有函数和变量
9- - 函数只能有一个参数
8+ type Pool struct {
9+ work chan func() // 任务 sem chan struct{} // 数量
10+ }
11+ func New(size int) *Pool {
12+ return &Pool{
13+ work: make(chan func()),
14+ sem: make(chan struct{}, size),
15+ }
16+ }
17+ func (p *Pool) Schedule(task func()) error { // 任务调度
18+ select {
19+ case p.work <- task:
20+ case p.sem <- struct{}{}:
21+ go p.worker(task)
22+ }
23+ }
24+ func (p *Pool) worker(task func()) { // 任务执行
25+ defer func() { <-p.sem }
26+ for {
27+ task()
28+ task = <-p.work
29+ }
30+ }
31+
32+ 协程池的调用
33+
34+ .. code :: go
35+
36+ pool := gopool.New(128)
37+ pool.Schedule(func(){
38+ fmt.println("task run")
39+ })
You can’t perform that action at this time.
0 commit comments