在 for 中使用 go 关键字,为什么不会不停创建 goroutine?

278 天前
 mingyuewandao
// Accept accepts connections on the listener and serves requests
// for each incoming connection.
func (server *Server) Accept(lis net.Listener) {
	for {
		conn, err := lis.Accept()
		if err != nil {
			log.Println("rpc server: accept error:", err)
			return
		}
               // 这里有问题:这里会不会不停创建 goroutine?
		go server.ServeConn(conn)
	}
}

https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-rpc/day1-codec/server.go#L143

2529 次点击
所在节点    Go 编程语言
9 条回复
sunny352787
278 天前
lis.Accept()是阻塞的
dhb233
278 天前
会创建啊,如果请求处理完了,goroutine 也会销毁
lsk569937453
278 天前
这个位置就是要不停的创建的 goroutine ,以保证后面的请求不会被未处理完的请求阻塞。
Vegetable
278 天前
当然是会不停创建的。
每个连接一个 goroutine ,数量取决于同时存在的连接数量。
yifeia
278 天前
accept 一个创建一个,只要 ServeConn 不阻塞,那 goroutine 执行完了就释放了,问题不大.
Cola98
278 天前
会不停创建,或者做一个简单的实验,你把这一段 for{
go xxx
}
抽出来看下
hingle
278 天前
在 go 上一行打印一下,就知道会不会了。
guonaihong
277 天前
因为 list.Accpet 只有新的连接过来,才会停止阻塞,所以这种写法的 go 程的个数等于连接 net.Conn 的个数。

另外聊个题外话,创建大量的 go 程,新版本 go 的 runtime 里面已经做了复用和优化。性能开销没有想象中那么大。
做过一个实验,使用 https://github.com/antlabs/quickws 这个 websocket 库,创建 100w 个 go 程,内存占用大约是 7.67GB 左右,8w tps 并发,50%的时延是 511.62ms

--------------------------------------------------------------
BenchType : BenchEcho
Framework : quickws
TPS : 86326
EER : 413.65
Min : -1ns
Avg : 573.50ms
Max : 1.44s
TP50 : 511.62ms
TP75 : 705.19ms
TP90 : 715.05ms
TP95 : 718.11ms
TP99 : 721.15ms
Used : 49.70s
Total : 5000000
Success : 4290729
Failed : 709271
Conns : 1000000
Concurrency: 50000
Payload : 1024
CPU Min : 120.52%
CPU Avg : 208.70%
CPU Max : 231.77%
MEM Min : 7.67G
MEM Avg : 7.67G
MEM Max : 7.67G
yc8332
276 天前
本来就是不停创建啊。但是要上面执行了才会到下面啊,没连接创个啥

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1017114

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX