kqueue用法簡介
阿新 • • 發佈:2020-11-04
kqueue用法簡介
什麼是kqueue和IO複用
kqueue是在UNIX上比較高效IO複用技術。
所謂的IO複用,就是同時等待多個檔案描述符就緒,以系統呼叫的形式提供。如果所有檔案描述符都沒有就緒的話,該系統呼叫阻塞,否則呼叫返回,允許使用者進行後續的操作。
常見的IO複用技術有select, poll, epoll以及kqueue等等。其中epoll為Linux獨佔,而kqueue則在許多UNIX系統上存在。
相關的資料結構
kqueue有三個主要的東西:struct kevent結構體,EV_SET巨集以及kevent函式。
struct kevent結構體是用於排程的事件
// struct kevent結構體 struct kevent { // 該事件關聯的檔案描述符,如socket中的fd控制代碼 uintptr_t ident; /* * 可以指定監聽型別 * 如EVFILT_READ=讀,EVFILT_WRITE=寫,EVFILT_TIMER=定時器事件,EVFILT_SIGNAL=訊號,EVFILT_USER=使用者自定義事件 */ int16_t filter; /** * 操作方式 * EV_ADD 新增,EV_DELETE 刪除,EV_ENABLE 啟用,EV_DISABLE 不啟用 */ uint16_t flags; uint32_t fflags; /* 第二種操作方式,NOTE_TRIGGER 立即啟用等等 */ intptr_t data; /* int 型的使用者資料,socket 裡面它是可讀寫的資料長度 */ void *udata; /* 指標型別的資料,你可以攜帶任何想攜帶的附加資料。比如物件 */ };
EV_SET是用於初始化kevent結構的便利巨集
EV_SET(&kev, ident, filter, flags, fflags, data, udata);
kevent函式
int kevent(int kq, // kqueue的控制代碼 const struct kevent *changelist, // 是 kevent 的陣列,就是一次可以新增多個事件 int nchanges, // 是 changelist 陣列長度 struct kevent *eventlist, // 是待接收事件的陣列,裡面是空的,準備給 kqueue 放資料的 int nevents, // 是 eventlist 陣列長度,傳了 eventlist引數後,kevent() 將會阻塞等待事件發生才返回,返回的全部事件在 eventlist 數組裡面。 const struct timespec *timeout); // 是阻塞超時時間,超過這個時間就不阻塞了,直接返回
使用kqueue
#include <sys/event.h> #include <sys/types.h> // 引入標頭檔案 int kq = kqueue(); // 獲取kqueue控制代碼 struct kevent evt; // 建立 EV_SET(&evt, sock, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, NULL); // 賦值 kevent(kq, &evt, 1, NULL, 0, NULL); // 新增 // 建立並新增監聽事件 struct kevent events[Max_Event_Count]; int ret = kevent(kq, NULL, 0, events, Max_Event_Count, NULL); // 監聽事件的發生 // kevent() 是阻塞呼叫,等到有事件才返回。阻塞時程序處於sleep狀態,有事件時系統啟用kqueue,kevent()返回 // events 是 kqueue 返回的事件陣列