golang 中处理大规模tcp socket网络连接的方法,相当于c语言的 poll 或 epoll
https://groups.google.com/forum/#!topic/golang-nuts/I7a_3B8_9Gw
https://groups.google.com/forum/#!msg/golang-nuts/coc6bAl2kPM/ypNLG3I4mk0J
ask: -----------------------
Hello,
That being said you should know that any goroutine blocking in a system call consumes one kernel thread. This will not be a problem until you need to support thousands of connections. But at this scale the file descriptor bitmaps used by select become a performance bottleneck as well. In this situation you might want to look at epoll on Linux. On other systems poll might be an alternative. If you are in this territory I strongly recommend to have a look into Michael Kerrisk's excellent reference "The LINUX Programming Interface".
It's true that a goroutine blocking in a syscall consumes a kernel thread. However, Receive1 will *not* use any kernel threads while waiting in conn.ReadFromUDP, because under the covers, the Go runtime uses nonblocking I/O for all network activity. It's much better just to rely on the runtime implementation of network I/O rather than trying to roll your own. If you don't believe me, try doing syscall traces or profiling to prove it out.
package main import (
"fmt"
"net"
"os"
"syscall"
) func Receive1(conn1, conn2 *net.UDPConn, done chan struct{}) <-chan string {
res := make(chan string)
tokenChan := make(chan []string) for _, conn := range []*net.UDPConn{conn1, conn2} {
go func(conn *net.UDPConn) {
buf := make([]byte, )
for {
select {
case <-done:
return
default:
if n, _, err := conn.ReadFromUDP(buf); err == nil {
fmt.Println(string(buf[:n]))
res <- string(buf[:n])
}
}
}
}(conn)
} return res
} func Receive2(conn1, conn2 *net.UDPConn, done chan struct{}) <-chan string {
res := make(chan string)
fds := &syscall.FdSet{}
filemap := map[int]*os.File{}
var maxfd =
for _, conn := range []*net.UDPConn{conn1, conn2} {
if file, err := conn.File(); err == nil {
fd := int(file.Fd())
FD_SET(fds, fd)
filemap[fd] = file
if fd > maxfd {
maxfd = fd
}
}
} go func() {
for {
select {
case <-done:
return
default:
fdsetCopy := *fds
tv := syscall.Timeval{, }
if _, err := syscall.Select(maxfd+, &fdsetCopy, nil, nil, &tv); err == nil {
for fd, file := range filemap {
if !FD_ISSET(&fdsetCopy, fd) {
continue
} buf := make([]byte, )
if n, err := file.Read(buf); err == nil {
fmt.Println(string(buf[:n]))
res <- string(buf[:n])
}
}
}
}
}
}() return res
} func FD_SET(p *syscall.FdSet, i int) {
p.Bits[i/] |= << (uint(i) % )
} func FD_ISSET(p *syscall.FdSet, i int) bool {
return (p.Bits[i/] & ( << (uint(i) % ))) !=
} func main() {
fmt.Println("Hello, playground")
}
Hello,It
is said that event-driven nonblocking model is not the preferred
programming model in Go, so I use "one goroutine for one client" model,
but is it OK to handle millions of concurrent goroutines in a server
process?
A goroutine itself is
4kb. So 1e6 goroutines would require 4gb of base memory. And then
whatever your server needs per goroutine that you add.
And, how can I "select" millions of channel to see which goroutine has data received?
not how it works. You just try to .Read() in each goroutine, and the
select is done under the hood. The select{} statement is for channel
communication, specifically.
event driven under the hood, but as far as the code you write, looks
linear. The Go runtime maintains a single thread that runs epoll or
kqueue or whatever under the hood, and wakes up a goroutine when new
data has arrived for that goroutine.
The
"select" statement can only select on predictable number of channels,
not on a lot of unpredictable channels. And how can I "select" a TCP
Connection (which is not a channel) to see if there is any data arrived?
Is there any "design patterns" on concurrent programming in Go?
golang 中处理大规模tcp socket网络连接的方法,相当于c语言的 poll 或 epoll的更多相关文章
- inux中,关于多路复用的使用,有三种不同的API,select、poll和epoll
inux中,关于多路复用的使用,有三种不同的API,select.poll和epoll https://www.cnblogs.com/yearsj/p/9647135.html 在上一篇博文中提到了 ...
- 在c#中利用keep-alive处理socket网络异常断开的方法
本文摘自 http://www.z6688.com/info/57987-1.htm 最近我负责一个IM项目的开发,服务端和客户端采用TCP协议连接.服务端采用C#开发,客户端采用Delphi开发.在 ...
- CentOS下netstat + awk 查看tcp的网络连接状态
执行以下命令: #netstat -n | awk ‘/^tcp/ {++state[$NF]} END {for(key in state) print key."\t".sta ...
- 【虚拟机】在VMware中安装Server2008之后配置网络连接的几种方式
VMware虚拟机的网络连接方式分为三种:桥接模式.NAT模式.仅主机(Host Only) (1)桥接模式 桥接模式即在虚拟机中虚拟一块网卡,这样主机和虚拟机在一个网段中就被看作是两个独立的IP地址 ...
- socket 网络连接基础
socket 客户端 import socket 1.client = socket.socket() # socket.TCP/IP 选择连接的类型,默认为本地连接 2.client.connec ...
- VC:检测网络连接的方法
方法一: #include "stdafx.h" #include "windows.h" #include <Sensapi.h> #includ ...
- golang中浮点型底层存储原理和decimal使用方法
var price float32 = 39.29 float64和float32类似,只是用于表示各部分的位数不同而已,其中:sign=1位,exponent=11位,fraction=52位,也就 ...
- 服务器中判断客户端socket断开连接的方法
1, 如果服务端的Socket比客户端的Socket先关闭,会导致客户端出现TIME_WAIT状态,占用系统资源. 所以,必须等客户端先关闭Socket后,服务器端再关闭Socket才能避免TIME_ ...
- 服务器中判断客户端socket断开连接的方法【转】
本文转载自:http://www.cnblogs.com/jacklikedogs/p/3976208.html 1, 如果服务端的Socket比客户端的Socket先关闭,会导致客户端出现TIME_ ...
随机推荐
- Kafka ACL使用实战
自0.9.0.0.版本引入Security之后,Kafka一直在完善security的功能.当前Kafka security主要包含3大功能:认证(authentication).信道加密(encry ...
- MySql 5.7 新特性概览
安全的提升 1.1 在Mysql 8版本中,caching_sha2_password 是一个缺省的认证插见.5.7 版本的客户端支持 caching_sha2_password 的客户端认证. 1. ...
- Mac下利用Cordova打包 iOS App以及出现的问题
安装 cordova sudo npm install cordova 创建项目 创建一个demo文件夹,里面自动加载基本的文件以及目录 cordova create demo com.test.de ...
- 使用python爬虫爬取股票数据
前言: 编写一个爬虫脚本,用于爬取东方财富网的上海股票代码,并通过爬取百度股票的单个股票数据,将所有上海股票数据爬取下来并保存到本地文件中 系统环境: 64位win10系统,64位python3.6, ...
- JQuery EasyUI Layout 在from布局自适应窗口大小
在JQuery EasyUI中,如果直接在form上布局时当窗口大小调整布局不会改变,将布局应用于body时中间隔着一个form,横竖不好弄. 网上有多个解决方案,一般都是写代码,在窗口大小改变时设置 ...
- DB2常用函数详解(一):字符串函数
VALUE函数 语法:VALUE(EXPRESSION1,EXPRESSION2) VALUE函数是用返回一个非空的值,当其第一个参数非空,直接返回该参数的值,如果第一个参数为空,则返回第一个参数的值 ...
- hdu2328 Corporate Identity【string库使用】【暴力】【KMP】
Corporate Identity Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- Ubuntu 16.04 编译OpenCV 问题解决stdlib.h: No such file or directory
https://blog.csdn.net/xinyu391/article/details/72867510 https://ask.csdn.net/questions/365969
- [No0000171]wpf 类层次结构Class Hierarchy
1.DispatcherObject类表示具有相关联的对象分派器.调度程序处理要在特定线程上执行工作的请求队列.它能够在其关联的线程上调用方法. DispatcherObject是对象的基类,用于跟踪 ...
- [Day2]变量、数据类型转换以及运算符
1.变量 变量是内存中装载数据的小盒子,你只能用它来存取数据 2.计算机存储单元 (1)计算机存储设备的最小信息单元叫“位(bit)”,“比特位” (2)8个比特位表示一个数据,是计算机的最小存储单元 ...