goroutine传统语言的网络层处理
read()write()上图中:
socket.accept()socketconnepollsocketepollepollreadwritewritewriteepollsocket这种模型的编程难度主要体现在:
- 线程少(也不能太多),导致一个线程需要处理多个描述符,从而存在对描述符状态的维护问题。甚至,业务层面的会话等都需要小心维护
- 非阻塞IO调用,使描述符的状态更为复杂
- 队列的同步处理
不得不说,能用C或C++来写服务器的是真大神!
Golang的goroutine
GolangGolang协程goroutinegogoroutinefunc main() {
log.Println("Hello, world")
netListen, err := net.Listen("tcp", "localhost:4000")
if err != nil {
fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())
os.Exit(1)
}
defer netListen.Close()
log.Println("Waiting for clients")
for {
conn, err := netListen.Accept()
if err != nil {
continue
}
log.Println(conn.RemoteAddr().String(), " tcp connect success")
go handleConnection(conn)
}
}
func handleConnection(conn net.Conn) {
...
}
Golang的channel
channelchannelgoroutinegoroutinechannelGolang如何实现网络层
goroutine上图是单个客户端连接的服务器模块结构,同样的一个颜色代表一个协程:
goroutineacceptconngoroutine阻塞读goroutine阻塞写读channelgoroutinegoroutine写channelgoroutinegoroutine再来看看多个客户端的情况:
goroutinegoroutinegoroutine