博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang实现异步并发sokect
阅读量:6948 次
发布时间:2019-06-27

本文共 3339 字,大约阅读时间需要 11 分钟。

hot3.png

搜索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 = 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: %f\n", 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 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://my.oschina.net/yunfound/blog/141222

你可能感兴趣的文章
QDialog之屏蔽Esc键
查看>>
Cocos2d-x-v3场景切换
查看>>
[置顶]白话贝叶斯理论及在足球比赛结果预测中的应用和C#实现
查看>>
HotSpotVM 对象机制实现浅析#1
查看>>
[android]android自动化测试
查看>>
为代码签名,供后人瞻仰或唾弃,你敢吗?
查看>>
Java笔记:集合框架实现原理
查看>>
用Objective-C写了一个简单的批量更改文件名的程序
查看>>
建立JDBC的环境配置和相关下载(Mac)
查看>>
Android 使用ViewPager结合PhotoView开源组件实现网络图片在线浏览功能
查看>>
GNU Radio中的数据元(Metadata)
查看>>
【JSP开发】URL路径的规范
查看>>
Android学习笔记(3):Android项目结构分析
查看>>
openlayers加载切片地图
查看>>
【Android开发】布局管理器-相对布局
查看>>
A Case about cursor_sharing=FORCE can introduce a execute plan stale
查看>>
[技术点]SQL 多条件查询
查看>>
PHP进阶~1
查看>>
thinking about application known or un-known distributed storage
查看>>
cocos2d::Map
查看>>