golang实现异步并发sokect
发布时间:2020-12-16 19:00:05 所属栏目:大数据 来源:网络整理
导读:搜索golang + epoll的例子,得到下面这段代码,感觉golang的编程思维真正做到了并行编程: package mainimport ("fmt""net""os""time")const (MAX_CONN_NUM = 5)//echo server Goroutinefunc EchoFunc(conn net.Conn) {defer conn.Close()buf := make([]byte,
搜索golang + epoll的例子,得到下面这段代码,感觉golang的编程思维真正做到了并行编程:
package main import ( "fmt" "net" "os" "time" ) const ( MAX_CONN_NUM = 5 ) //echo server Goroutine func EchoFunc(conn net.Conn) { defer conn.Close() buf := make([]byte,1024) for { _,err := conn.Read(buf) if err != nil { //println("Error reading:",err.Error()) return } //send reply _,err = conn.Write(buf) if err != nil { //println("Error send reply:",err.Error()) return } } } //initial listener and run func main() { listener,err := net.Listen("tcp","0.0.0.0:8088") if err != nil { fmt.Println("error listening:",err.Error()) os.Exit(1) } defer listener.Close() fmt.Printf("running ...n") var cur_conn_num int = 0 conn_chan := make(chan net.Conn) ch_conn_change := make(chan int) go func() { for conn_change := range ch_conn_change { cur_conn_num += conn_change } }() go func() { for _ = range time.Tick(1e8) { fmt.Printf("cur conn num: %fn",cur_conn_num) } }() for i := 0; i < MAX_CONN_NUM; i++ { go func() { for conn := range conn_chan { ch_conn_change <- 1 EchoFunc(conn) ch_conn_change <- -1 } }() } for { conn,err := listener.Accept() if err != nil { println("Error accept:",err.Error()) return } conn_chan <- conn } } 再看这段代码使用传统思维实行方式:
// //A echo server with max-connections limit and interval connection show // package main import ( "fmt" "net" "os" "time" ) const ( MAX_CONN_NUM = 5 ) //echo server Goroutine func EchoFunc(conn net.Conn,conn_close_flag chan int) { defer conn.Close() defer func() { conn_close_flag <- -1 }() buf := make([]byte,1024) for { _,err := conn.Read(buf) if err != nil { //println("Error reading:",err.Error()) return } //send reply _,err = conn.Write(buf) if err != nil { //println("Error send reply:",err.Error()) return } } } //initial listener and run func main() { listener,"0.0.0.0:8088") if err != nil { println("error listening:",err.Error()) os.Exit(1) } defer listener.Close() fmt.Printf("running ...n") var cur_conn_num float64 = 0 ch_conn_change := make(chan int,MAX_CONN_NUM) tick := time.Tick(1e8) for { //read all close flags berfor accept new connection //TODO: better code to handle batch close? readmore := 1 for readmore > 0 { select { case conn_change := <-ch_conn_change: cur_conn_num = cur_conn_num + float64(conn_change) default: readmore = 0 } } //FIXME: tick block by listener.Accept() select { case <-tick: fmt.Printf("cur conn num: %fn",cur_conn_num) default: } if cur_conn_num >= MAX_CONN_NUM { //reach MAX_CONN_NUM,waiting for exist connection close time.Sleep(time.Second) } else { //accept new connetion conn,err := listener.Accept() if err != nil { println("Error accept:",err.Error()) return } cur_conn_num++ go EchoFunc(conn,ch_conn_change) } } } 这个案例中,golang通过多个goroutine + channel堵塞做到传统的顺序执行模式。 代码来自google group的讨论:https://groups.google.com/forum/#!topic/golang-china/q4pFH-AGnfs (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |