Yes, the Go runtime does use epoll internally and schedules gorountines 
when their data is available. 
See 
https://github.com/golang/go/blob/17b2fb1b656a275906b5071c562439d50a27f167/src/runtime/netpoll_epoll.go
It does scale nicely and can handle tens of thousands or even hundreds of 
thousands of concurrent connections, without the "Thundering 
Herd" type behaviour which one would expect from such systems.
I have not tried it with millions of connection, but if you are interested, 
then run a test, but the consume side of your test will run out of ports.

On Wednesday, 6 April 2022 at 14:43:16 UTC+1 Jack Li wrote:

> Hi group,
>
> I am going through this page: https://studygolang.com/articles/22820 , It 
> claims that the 50 lines of Go code handles 1 million concurrent 
> connections from network clients, on 1 single server machine with a 4-Core 
> CPU and 16G memory.
>
> Does the package net already utilize IO Multiplexing internally, like 
> epoll (epoll_create, epoll_ctl, epoll_wait)? So I can just use package net 
> and gain the epoll ability automatically without calling epoll apis 
> manually in Go?
>
> Thanks
>
> Server:
> ```
> package main
>
> import (
>     "fmt"
>     "net"
>     "os"
>     "time"
> )
>
> var array []byte = make([]byte, 10)
>
> func checkError(err error, info string) (res bool) {
>
>     if err != nil {
>         fmt.Println(info + "  " + err.Error())
>         return false
>     }
>     return true
> }
>
> func Handler(conn net.Conn) {
>     for {
>         _, err := conn.Write(array)
>         if err != nil {
>             return
>         }
>         time.Sleep(10 * time.Second)
>     }
> }
>
> func main() {
>
>     for i := 0; i < 10; i += 1 {
>         array[i] = 'a'
>     }
>
>     service := ":8888"
>     tcpAddr, _ := net.ResolveTCPAddr("tcp4", service)
>     l, _ := net.ListenTCP("tcp", tcpAddr)
>
>     for {
>         conn, err := l.Accept()
>         if err != nil {
>             fmt.Printf("accept error, err=%s\n", err.Error())
>             os.Exit(1)
>         }
>         go Handler(conn)
>     }
>
> }
> ```
>
> Client:
>
> ```
> package main
>
> import (
>     "flag"
>     "fmt"
>     "net"
>     "os"
>     "time"
> )
>
> var RemoteAddr *string
> var ConcurNum *int
> var LocalAddr *string
>
> func init() {
>     RemoteAddr = flag.String("remote-ip", "127.0.0.1", "ip addr of remote 
> server")
>     ConcurNum = flag.Int("concurrent-num", 100, "concurrent number of 
> client")
>     LocalAddr = flag.String("local-ip", "0.0.0.0", "ip addr of remote 
> server")
> }
>
> func consume() {
>
>     laddr := &net.TCPAddr{IP: net.ParseIP(*LocalAddr)}
>
>     var dialer net.Dialer
>     dialer.LocalAddr = laddr
>
>     conn, err := dialer.Dial("tcp", *RemoteAddr+":8888")
>     if err != nil {
>         fmt.Println("dial failed:", err)
>         os.Exit(1)
>     }
>     defer conn.Close()
>
>     buffer := make([]byte, 512)
>
>     for {
>         _, err2 := conn.Read(buffer)
>         if err2 != nil {
>             fmt.Println("Read failed:", err2)
>             return
>         }
>
>         //  fmt.Println("count:", n, "msg:", string(buffer))
>
>     }
>
> }
>
> func main() {
>     flag.Parse()
>     for i := 0; i < *ConcurNum; i++ {
>         go consume()
>     }
>     time.Sleep(3600 * time.Second)
> }
> ```
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/e139c771-4b11-49c6-9045-ed65c861ded2n%40googlegroups.com.

Reply via email to