單路:一個IO給它專門開一個線程處理澎嚣。
多路:多個IO復(fù)用一個線程處理。(節(jié)約線程瘟芝,內(nèi)存)
kqueue 是 unix 下的一個IO多路復(fù)用庫易桃。
引用頭文件
#include <sys/event.h>
#include <sys/types.h>
創(chuàng)建 kqueue,獲得句柄 kq锌俱,后面要通過 kq 操作 kqueue
int kq = kqueue();
向 kqueue 中添加一個需要關(guān)心的事件
struct kevent evt; // 創(chuàng)建
EV_SET(&evt, sock, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, NULL); // 賦值
kevent(kq, &evt, 1, NULL, 0, NULL); // 添加
上面的代碼解釋
kevent 是個結(jié)構(gòu)體
struct kevent {
uintptr_t ident; /* identifier for this event */
int16_t filter; /* filter for event */
uint16_t flags; /* general flags */
uint32_t fflags; /* filter-specific flags */
intptr_t data; /* filter-specific data */
void *udata; /* opaque user data identifier */
};
/* --- 解釋:--- */
ident 是事件唯一的 key晤郑,在 socket 使用中,它是 socket 的 fd 句柄
filter 是事件的類型,有 15 種造寝,其中幾種常用的是
EVFILT_READ socket 可讀事件
EVFILT_WRITE socket 可寫事件
EVFILT_SIGNAL unix 系統(tǒng)的各種信號
EVFILT_TIMER 定時器事件
EVFILT_USER 用戶自定義的事件
flags 操作方式磕洪,EV_ADD 添加,EV_DELETE 刪除诫龙,EV_ENABLE 激活析显,EV_DISABLE 不激活
fflags 第二種操作方式,NOTE_TRIGGER 立即激活等等
data int 型的用戶數(shù)據(jù)签赃,socket 里面它是可讀寫的數(shù)據(jù)長度
udata 指針類型的數(shù)據(jù)谷异,你可以攜帶任何想攜帶的附加數(shù)據(jù)。比如對象
kevent() 可以往 kqueue 里添加事件锦聊,或者監(jiān)聽事件歹嘹,kevent() 是阻塞調(diào)用的
int kevent( int kq,
const struct kevent *changelist,
int nchanges,
struct kevent *eventlist,
int nevents,
const struct timespec *timeout);
/* --- 解釋:--- */
kq 就是 kqueue 的句柄
changelist 是 kevent 的數(shù)組,就是一次可以添加多個事件
nchanges 是 changelist 數(shù)組長度
eventlist 是待接收事件的數(shù)組括丁,里面是空的荞下,準備給 kqueue 放數(shù)據(jù)的
nevents 是 eventlist 數(shù)組長度
傳了 eventlist伶选,kevent() 將會阻塞等待事件發(fā)生才返回史飞,返回的全部事件在 eventlist 數(shù)組里面。
timeout 是阻塞超時時間仰税,超過這個時間就不阻塞了构资,直接返回
在 kqueue 中監(jiān)聽事件的發(fā)生
struct kevent events[Max_Event_Count];
int ret = kevent(kq, NULL, 0, events, Max_Event_Count, NULL);
// kevent() 是阻塞調(diào)用,等到有事件才返回陨簇。
// events 是 kqueue 返回的事件數(shù)組
kqueue 可以監(jiān)聽 socket吐绵,文件變化,系統(tǒng)信號河绽,定時器事件己单,用戶自定義事件。
一般用來監(jiān)聽 socket 的事件耙饰,是否可讀纹笼,可寫等等,能處理大量socket IO 請求苟跪,性能較高廷痘,原理見操作系統(tǒng)中的I/O,及高性能IO模型
用戶可以自定義一些事件來控制 kqueue 開啟或退出件已。
定時器事件笋额,GCD 的 dispatch_after 就是直接用了 kqueue 的定時器事件,可以設(shè)置間隔多少秒后做什么操作篷扩。
參考文獻:
kqueue文檔
kqueue原論文
kqueue例子
使用 kqueue 在 FreeBSD 上開發(fā)高性能應(yīng)用服務(wù)器