golang中基於kevent的IO多路複用實踐

zongzw發表於2024-06-02

https://github.com/zongzw-learn/learn-go/tree/master/basics/tcp-poller

kqueue在golang語言下的使用實踐

將kqueue的操作細節封裝在NetPoller介面中,實現KqueuePoller的三個API:

  • Start 啟動基於kqueue的IO多路複用事件監聽
  • Close 停止kqueue
  • SetHandler 設定可插入式的資料處理函式,目前只處理socket讀取操作。亦可以根據需要新增寫操作

使用方法參考 main函式

原理

  • syscall + kqueue + kevent + socket API

核心程式碼解讀

			n, err := syscall.Kevent(np.kq, nil, np.events, nil)
			if err != nil {
				// ...
			}
			for i := 0; i < n; i++ {
				ev := np.events[i]
				if ev.Ident == uint64(np.socket) {
					// 對於server socket的事件處理
					// ...
				} else {
					// 對於客戶socket的事件處理
					switch ev.Filter {
					case syscall.EVFILT_READ:
						b, err := np.readFd(int(ev.Ident))
						if err != nil {
							if err == io.EOF {
								// 客戶socket的關閉情況
								syscall.Close(int(ev.Ident))
							} else {
								log.Printf("failed to read from socket %d: %s", ev.Ident, err.Error())
							}
						} else {
							// 客戶socket的讀操作
						}
					case syscall.EVFILT_WRITE:
						// 客戶socket的寫操作
					default:
						log.Printf("not supported for Filter type: %d", ev.Filter)
					}
				}
			}

相關文章