Multithreading GO:在简单tcp服务器上超过10000个线程?

Multithreading GO:在简单tcp服务器上超过10000个线程?,multithreading,tcp,go,Multithreading,Tcp,Go,我需要写一个tcp服务器,可以处理超过500k的连接 我在golang上编写了一个简单的服务器,但是当连接数超过10k时,服务器崩溃,错误消息为“runtime:program Over 10000 thread limit致命错误:thread Expension” 服务器在上一个linux版本中运行。go可以使用epoll进行tcp连接,使其异步并使用很少的fd。那么为什么服务器超过了线程限制 我的简单服务器: package main import ( "strconv"

我需要写一个tcp服务器,可以处理超过500k的连接

我在golang上编写了一个简单的服务器,但是当连接数超过10k时,服务器崩溃,错误消息为“runtime:program Over 10000 thread limit致命错误:thread Expension”

服务器在上一个linux版本中运行。go可以使用epoll进行tcp连接,使其异步并使用很少的fd。那么为什么服务器超过了线程限制

我的简单服务器:

package main
import (
    "strconv"
    "net"
    "log"
    "time"
    "bufio"
    "io"
)

type Handler struct {
    conn   net.Conn
    closed chan bool
}

func (h *Handler) Listen() { // listen connection for incomming data
    defer h.conn.Close()
    bf := bufio.NewReader(h.conn)
    for {
        line, _, err := bf.ReadLine()
        if err != nil {
            if err == io.EOF {
                log.Println("End connection")
            }
            h.closed <- true // send to dispatcher, that connection is closed
            return
        }

        // ... some business logic with data
    }
}

type Dispatcher struct {
    handlers map[string]*Handler `map[ip]*Handler`
}

func (d *Dispatcher) AddHandler(conn net.Conn) {
    addr := conn.RemoteAddr().String()
    handler := &Handler{conn, make(chan bool, 1)}
    d.handlers[addr] = handler

    go handler.Listen()

    <-handler.closed // when connection closed, remove handler from handlers
    delete(d.handlers, addr)
}

func (d *Dispatcher) ListenHandlers(port int) {
    sport := strconv.Itoa(port)

    ln, err := net.Listen("tcp", ":" + sport)
    if err != nil {
        log.Println(err)
        return
    }

    defer ln.Close()

    for {
        conn, err := ln.Accept() // accept connection
        if err != nil {
            log.Println(err)
            continue
        }

        tcpconn := conn.(*net.TCPConn)
        tcpconn.SetKeepAlive(true)
        tcpconn.SetKeepAlivePeriod(10 * time.Second)

        go d.AddHandler(conn)
    }
}

func main() {
    dispatcher := &Dispatcher{make(map[string]*Handler)}
    dispatcher.ListenHandlers(3000)
}
主程序包
进口(
“strconv”
“净额”
“日志”
“时间”
“布菲奥”
“io”
)
类型处理程序结构{
康涅狄格州
闭门禅院
}
func(h*处理程序)Listen(){//Listen连接用于输入数据
延迟h.conn.关闭()
bf:=bufio.NewReader(康涅狄格州h.conn)
为了{
第行,u,err:=bf.ReadLine()
如果错误!=零{
如果err==io.EOF{
log.Println(“端连接”)
}
h、 关闭问题是那个图书馆。
这个库获取套接字文件描述符(fd),然后复制并使用新的fd,该fd在阻塞模式下运行。因此,在每个连接上创建新线程。不要杀死创建的线程(因为这是本机golang行为),在一些时间后,go以“超过10000个线程”失败。就是这样!

请不要使用它:)

每当goroutine进行阻塞系统调用或调用库中的C代码时,go都会为其他goroutine使用新线程。我怀疑注释为
/…某些带有数据的业务逻辑
有阻塞,导致go旋转额外的goroutine。您是否有机会在在第部分?@sintanial:Go的
net
包将使用epoll/select将读写多路传输到多个套接字。您是否尝试使用gdb检查应用程序,以查看当您看到此错误时所有线程都在做什么?TCP连接在每个对等机上使用一个端口。端口由16位数字表示,因此您有一个技术问题限制一个IP地址上的TCP连接数,这与你的目标0.5M连接数相差甚远。你想做什么?@UlrichEckhardt AFAIK从多个源地址和端口,你可以有超过65k个连接,因为每个连接有两个由其标识的地址。@Not a_Golfer你是对的。我删除了我的业务逻辑,运行了服务器,它工作正常。运行在34个线程中,仅此而已,线程没有增加:)。Thx对于您,我认为在golang问题中:)