Go语言基于Channel实现计数器出现跳值问题求助
问题分析与解决
问题概述
编写的Go HTTP服务器程序,预期在页面上依次显示0、1、2……递增的计数器值,但实际输出为0、2、4、6……的跳值情况。
源代码
package main import ( "fmt" "log" "net/http" ) type nextChan chan int func(ch nextChan) handle(writer http.ResponseWriter, req *http.Request){ fmt.Fprintf(writer,"<h1> Counter value is %d </h1>",<-ch) } func counter(ch chan <-int){ for i:=0; ;i++{ ch <- i } } func main(){ var nextId nextChan = make(chan int) go counter(nextId) http.HandleFunc("/",nextId.handle) log.Fatal(http.ListenAndServe(":8080",nil)) }
原因解析
跳值的核心原因是浏览器会自动发送额外请求:当你访问页面时,浏览器除了请求根路径/,还会自动请求/favicon.ico(用于显示页面标签栏图标)。每次请求都会触发handle函数,从Channel中读取一个计数器值。
比如:
- 首次访问:
/请求读取0(页面显示0),/favicon.ico请求读取1(该值被消耗但无可见输出) - 刷新页面:
/请求读取2(页面显示2),/favicon.ico请求读取3(同样被隐藏消耗)
循环往复,就出现了页面显示值跳增的情况。
解决方案
只需过滤非根路径的请求,避免额外请求消耗Channel值,有两种常见实现方式:
方式1:在handle函数中判断请求路径
func(ch nextChan) handle(writer http.ResponseWriter, req *http.Request){ // 仅处理根路径请求,其他路径返回404 if req.URL.Path != "/" { http.NotFound(writer, req) return } fmt.Fprintf(writer,"<h1> Counter value is %d </h1>",<-ch) }
方式2:单独注册favicon的空处理函数
func main(){ var nextId nextChan = make(chan int) go counter(nextId) http.HandleFunc("/",nextId.handle) // 给favicon注册空处理函数,不消耗计数器值 http.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {}) log.Fatal(http.ListenAndServe(":8080",nil)) }
内容的提问来源于stack exchange,提问作者Shivam...
相关产品推荐
相关产品推荐

