The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
josexy

Go 的网络轮询器疑惑?

  •  
  •   josexy ·
    josexy · Apr 3, 2022 · 2961 views
    This topic created in 1502 days ago, the information mentioned may be changed or developed.

    最近我在看 Go 的网络轮询器相关文章时,从源码看到 netpollinit 是通过 nonblockingPipe() 创建读写管道 来中断 epollwait ,为什么同样是 Linux 下不使用 eventfd 唤醒事件?有什么原因吗?

    https://github.com/golang/go/blob/master/src/runtime/netpoll.go

    func netpollinit() {
    	epfd = epollcreate1(_EPOLL_CLOEXEC)
    	if epfd < 0 {
    		epfd = epollcreate(1024)
    		if epfd < 0 {
    			println("runtime: epollcreate failed with", -epfd)
    			throw("runtime: netpollinit failed")
    		}
    		closeonexec(epfd)
    	}
    	r, w, errno := nonblockingPipe()
    	if errno != 0 {
    		println("runtime: pipe failed with", -errno)
    		throw("runtime: pipe failed")
    	}
    	ev := epollevent{
    		events: _EPOLLIN,
    	}
    	*(**uintptr)(unsafe.Pointer(&ev.data)) = &netpollBreakRd
    	errno = epollctl(epfd, _EPOLL_CTL_ADD, r, &ev)
    	if errno != 0 {
    		println("runtime: epollctl failed with", -errno)
    		throw("runtime: epollctl failed")
    	}
    	netpollBreakRd = uintptr(r)
    	netpollBreakWr = uintptr(w)
    }
    
    // netpollBreak interrupts an epollwait.
    func netpollBreak() {
    	if atomic.Cas(&netpollWakeSig, 0, 1) {
    		for {
    			var b byte
    			n := write(netpollBreakWr, unsafe.Pointer(&b), 1)
    			if n == 1 {
    				break
    			}
    			if n == -_EINTR {
    				continue
    			}
    			if n == -_EAGAIN {
    				return
    			}
    			println("runtime: netpollBreak write failed with", -n)
    			throw("runtime: netpollBreak write failed")
    		}
    	}
    }
    
    
    3 replies    2022-04-05 09:54:52 +08:00
    lesismal
        1
    lesismal  
       Apr 3, 2022
    我不敢说这就是原因,只作为猜测:
    1. pipe 和 event 都可以实现功能
    2. pipe 每次只需要 write 1 字节,而 eventfd 每次必须写入大于等于 8 字节、相比之下浪费
    nuk
        2
    nuk  
       Apr 4, 2022
    内核版本要求吧,不然 eventfd 应该是更好的选择
    mengzhuo
        3
    mengzhuo  
       Apr 5, 2022
    主要考虑是 netpollBreak

    https://github.com/golang/go/issues/27707
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   989 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 22:05 · PVG 06:05 · LAX 15:05 · JFK 18:05
    ♥ Do have faith in what you're doing.