From b242141e227ecbfe3f48dd2c9c8988ecb5d5bba0 Mon Sep 17 00:00:00 2001 From: yusuf Date: Fri, 2 Aug 2019 12:16:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B014=E3=80=8115=E5=92=8C17?= =?UTF-8?q?=E7=AB=A0=E7=9B=AE=E5=BD=95=20(#702)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 更新14、15和17章目录 * Update README.md * 添加章节序号 * 添加章节序号 * 添加代码链接 * 修改错别字 * 删除多余字符 * 修复代码与文件不对应的问题 * 修改代码 --- README.md | 2 +- eBook/14.10.md | 28 ++++++++++++---------------- eBook/14.13.md | 2 +- eBook/14.8.md | 2 +- eBook/17.2.md | 2 +- eBook/17.3.md | 2 +- eBook/directory.md | 22 ++++++++++++++++++++-- 7 files changed, 37 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 096080f..e337dd8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## 翻译进度 -14.9 [实现 Futures 模式](eBook/14.9.md) +18.11 [出于性能考虑的最佳实践和建议](eBook/18.11.md) ## 支持本书 diff --git a/eBook/14.10.md b/eBook/14.10.md index 5506529..3c70da9 100644 --- a/eBook/14.10.md +++ b/eBook/14.10.md @@ -4,7 +4,7 @@ 客户端-服务器应用正是 goroutines 和 channels 的亮点所在。 -客户端(Client)可以是运行在任意设备上的任意程序,它会按需发送请求(request)至服务器。服务器(Server)接收到这个请求后开始相应的工作,然后再将响应(response)返回给客户端。典型情况下一般是多个客户端(既多个请求)对应一个(或少量)服务器。例如我们日常使用的浏览器客户端,其功能就是向服务器请求网页。而Web服务器则会向浏览器响应网页数据。 +客户端(Client)可以是运行在任意设备上的任意程序,它会按需发送请求(request)至服务器。服务器(Server)接收到这个请求后开始相应的工作,然后再将响应(response)返回给客户端。典型情况下一般是多个客户端(即多个请求)对应一个(或少量)服务器。例如我们日常使用的浏览器客户端,其功能就是向服务器请求网页。而Web服务器则会向浏览器响应网页数据。 使用Go的服务器通常会在协程中执行向客户端的响应,故而会对每一个客户端请求启动一个协程。一个常用的操作方法是客户端请求自身中包含一个通道,而服务器则向这个通道发送响应。 @@ -35,7 +35,7 @@ func run(op binOp, req *Request) { req.replyc <- op(req.a, req.b) } ``` -`server`协程会无限循环以从`chan \*Request`接收请求,并且为了避免被长时间操作所堵塞,它将为每一个请求启动一个协程来做具体的工作: +`server`协程会无限循环以从`chan *Request`接收请求,并且为了避免被长时间操作所堵塞,它将为每一个请求启动一个协程来做具体的工作: ```go func server(op binOp, service chan *Request) { @@ -112,26 +112,22 @@ func run(op binOp, req *Request) { req.replyc <- op(req.a, req.b) } -func server(op binOp, service chan *Request, quit chan bool) { +func server(op binOp, service chan *Request) { for { - select { - case req := <-service: - go run(op, req) - case <-quit: - return - } + req := <-service // requests arrive here + // start goroutine for request: + go run(op, req) // don't wait for op } } -func startServer(op binOp) (service chan *Request, quit chan bool) { - service = make(chan *Request) - quit = make(chan bool) - go server(op, service, quit) - return service, quit +func startServer(op binOp) chan *Request { + reqChan := make(chan *Request) + go server(op, reqChan) + return reqChan } func main() { - adder, quit := startServer(func(a, b int) int { return a + b }) + adder := startServer(func(a, b int) int { return a + b }) const N = 100 var reqs [N]Request for i := 0; i < N; i++ { @@ -149,9 +145,9 @@ func main() { fmt.Println("Request ", i, " is ok!") } } - quit <- true fmt.Println("done") } + ``` ## 14.10.2 卸载(Teardown):通过信号通道关闭服务器 diff --git a/eBook/14.13.md b/eBook/14.13.md index cb4bbac..515becc 100644 --- a/eBook/14.13.md +++ b/eBook/14.13.md @@ -23,7 +23,7 @@ func DoPart(sem chan int) { } func main() { - runtime.GOMAXPROCS = NCPU + runtime.GOMAXPROCS(NCPU) // runtime.GOMAXPROCS = NCPU DoAll() } diff --git a/eBook/14.8.md b/eBook/14.8.md index c837c1d..a98e10c 100644 --- a/eBook/14.8.md +++ b/eBook/14.8.md @@ -117,7 +117,7 @@ func BuildLazyIntEvaluator(evalFunc EvalFunc, initState Any) func() int { 9th even: 18 ``` -练习14.12:general_lazy_evaluation2.go +练习14.12:[general_lazy_evaluation2.go](exercises/chapter_14/general_lazy_evalution2.go) 通过使用14.12中工厂函数生成前10个斐波那契数 提示:因为斐波那契数增长很迅速,使用`uint64`类型。 diff --git a/eBook/17.2.md b/eBook/17.2.md index a914b23..daf9af5 100644 --- a/eBook/17.2.md +++ b/eBook/17.2.md @@ -1,4 +1,4 @@ -# defer 模式 +# 17.2 defer 模式 使用 `defer` 可以确保资源不再需要时,都会被恰当地关闭或归还到“池子”中。更重要的一点是,它可以恢复 panic。 diff --git a/eBook/17.3.md b/eBook/17.3.md index 36d843d..85a6c87 100644 --- a/eBook/17.3.md +++ b/eBook/17.3.md @@ -1,4 +1,4 @@ -# 可见性模式 +# 17.3 可见性模式 我们在 [4.2.1节](04.2.md) 见过简单地使用可见性规则控制对类型成员的访问,他们可以是 Go 变量或函数。[10.2.1节](10.2.md) 展示了如何在单独的包中定义类型时,强制使用工厂函数。 diff --git a/eBook/directory.md b/eBook/directory.md index 24c8691..2322b1e 100644 --- a/eBook/directory.md +++ b/eBook/directory.md @@ -145,12 +145,27 @@ - 14.7 [新旧模型对比:任务和worker](14.7.md) - 14.8 [惰性生成器的实现](14.8.md) - 14.9 [实现 Futures 模式](14.9.md) - + - 14.10 [复用](14.10.md) + - 14.11 [限制同时处理的请求数](14.11.md) + - 14.12 [链式协程](14.12.md) + - 14.13 [在多核心上并行计算](14.13.md) + - 14.14 [并行化大量数据的计算](14.14.md) + - 14.15 [漏桶算法](14.15.md) + - 14.16 [对Go协程进行基准测试](14.16.md) + - 14.17 [使用通道并发访问对象](14.17.md) - 第15章:[网络、模版与网页应用](15.0.md) - 15.1 [tcp服务器](15.1.md) - 15.2 [一个简单的web服务器](15.2.md) - 15.3 [访问并读取页面数据](15.3.md) - 15.4 [写一个简单的网页应用](15.4.md) + - 15.5 [确保网页应用健壮](15.5.md) + - 15.6 [用模板编写网页应用](15.6.md) + - 15.7 [探索 template 包](15.7.md) + - 15.8 [精巧的多功能网页服务器](15.8.md) + - 15.9 [用 rpc 实现远程过程调用](15.9.md) + - 15.10 [基于网络的通道 netchan](15.10.md) + - 15.11 [与 websocket 通信](15.11.md) + - 15.12 [用 smtp 发送邮件](15.12.md) ## 第四部分:实际应用 @@ -166,7 +181,10 @@ - 16.9 [闭包和协程的使用](16.9.md) - 16.10 [糟糕的错误处理](16.10.md) - 第17章:[模式](17.0.md) - - 17.1 [关于逗号ok模式](17.1.md) + - 17.1 [逗号ok模式](17.1.md) + - 17.2 [defer 模式](17.2.md) + - 17.3 [可见性模式](17.3.md) + - 17.4 [运算符模式和接口](17.4.md) - 第18章:[出于性能考虑的实用代码片段](18.0.md) - 18.1 [字符串](18.1.md) - 18.2 [数组和切片](18.2.md)