golang實現非同步並發sokect

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。搜尋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, 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 runfunc 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 = 0conn_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: %f\n", cur_conn_num)}}()for i := 0; i < MAX_CONN_NUM; i++ {go func() {for conn := range conn_chan {ch_conn_change <- 1EchoFunc(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 mainimport (    "fmt"    "net"    "os"    "time")const (    MAX_CONN_NUM = 5)//echo server Goroutinefunc 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 runfunc main() {    listener, err := net.Listen("tcp", "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: %f\n", 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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.