Golang Go语言中在 for 中使用 go 关键字,为什么不会不停创建 goroutine?
// 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)
}
}
Golang Go语言中在 for 中使用 go 关键字,为什么不会不停创建 goroutine?
更多关于Golang Go语言中在 for 中使用 go 关键字,为什么不会不停创建 goroutine?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
lis.Accept()是阻塞的
更多关于Golang Go语言中在 for 中使用 go 关键字,为什么不会不停创建 goroutine?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
会创建啊,如果请求处理完了,goroutine 也会销毁
这个位置就是要不停的创建的 goroutine ,以保证后面的请求不会被未处理完的请求阻塞。
当然是会不停创建的。
每个连接一个 goroutine ,数量取决于同时存在的连接数量。
accept 一个创建一个,只要 ServeConn 不阻塞,那 goroutine 执行完了就释放了,问题不大.
会不停创建,或者做一个简单的实验,你把这一段 for{
go xxx
}
抽出来看下
在 go 上一行打印一下,就知道会不会了。
因为 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
本来就是不停创建啊。但是要上面执行了才会到下面啊,没连接创个啥
在Golang(Go语言)中,虽然在for
循环中使用go
关键字可以启动新的goroutine,但并不会无限制地不停创建goroutine,这主要归因于Go的运行时调度机制以及编程实践中的控制手段。
-
调度器限制:Go的运行时有一个高效的调度器,它会管理goroutine的创建、调度和执行。当系统资源(如CPU和内存)有限时,调度器会限制goroutine的并发数量,避免系统过载。
-
通道(Channel)与同步机制:在实际编程中,通常会使用通道(channel)或其他同步机制来控制goroutine的创建和执行。例如,可以通过带缓冲的通道来限制同时运行的goroutine数量,或者通过无缓冲通道来确保goroutine按顺序执行。
-
程序逻辑控制:开发者可以在
for
循环中添加逻辑判断,根据特定条件来决定是否启动新的goroutine。这种控制可以基于外部输入、内部状态或性能监控等。 -
资源限制:操作系统层面的资源限制(如文件描述符数量、内存配额等)也会间接影响goroutine的创建。当资源耗尽时,新的goroutine将无法被创建。
综上所述,虽然在for
循环中使用go
关键字看似可以无限创建goroutine,但实际上由于Go的运行时机制、编程实践中的控制手段以及系统资源限制,这种情况并不会发生。因此,开发者可以放心地在需要时使用goroutine来并发执行任务,同时也要注意合理控制并发数量,避免资源浪费和性能问题。