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)
}
}
}