redis伺服器是乙個事件驅動的程式,內部需要處理兩類事件,一類是檔案事件(file event),一類是時間事件(time event),前者對應著處理各種io事件,後者對應著處理各種定時任務。
印象中我們都知道redis是單執行緒服務,其實本質上的確就是這樣子的,上面說的file event 和 time event都是由單個執行緒驅動的,file event 底層其實是通過select/epoll等模型去執行驅動的,time event是通過內部維持乙個定時任務列表來實現的。
redis server的事件模型其實就是經典的nio模型,底層通過select/epoll等機制實現非同步nio,通過檢測到event到來後for迴圈實現序列處理。
redis server的main函式在啟動過程中按照以下三個步驟進行初始化並進入執行狀態:
int main(int argc, char **ar**)
void initserver()
// 為 tcp 連線關聯連線應答(accept)處理器,用於接受並應答客戶端的 connect() 呼叫
for (j = 0; j < server.ipfd_count; j++)
}}
aecreatefileevent方法內部關鍵點在於aeapiaddevent這個方法,將fd繫結到具體的eventloop當中
/*
* 根據 mask 引數的值,監聽 fd 檔案的狀態,
* 當 fd 可用時,執行 proc 函式
*/int aecreatefileevent(aeeventloop *eventloop, int fd, int mask,
aefileproc *proc, void *clientdata)
if (fd >= eventloop->setsize) return ae_err;
// 取出檔案事件結構
aefileevent *fe = &eventloop->events[fd];
// 監聽指定 fd 的指定事件
if (aeapiaddevent(eventloop, fd, mask) == -1)
return ae_err;
// 設定檔案事件型別,以及事件的處理器
fe->mask |= mask;
if (mask & ae_readable) fe->rfileproc = proc;
if (mask & ae_writable) fe->wfileproc = proc;
// 私有資料
fe->clientdata = clientdata;
// 如果有需要,更新事件處理器的最大 fd
if (fd > eventloop->maxfd)
eventloop->maxfd = fd;
return ae_ok;
}
整個accept的處理過程按照anettcpaccept -> acceptcommonhandler -> createclient -> aecreatefileevent實現socket的accept並註冊到eventloop。
void accepttcphandler(aeeventloop *el, int fd, void *privdata, int mask)
} static void acceptcommonhandler(int fd, int flags)
}redisclient *createclient(int fd)
}//此處省略很多**
}
redis server啟動事件處理的主迴圈,會迴圈執行aeprocessevents方法。
/*
* 事件處理器的主迴圈
*/void aemain(aeeventloop *eventloop)
}
aeprocessevents方法有乙個非常巧妙的實現,在內部需要同時處理time event 和 file event,那麼如何處理先後問題呢。思路如下:
int aeprocessevents(aeeventloop *eventloop, int flags)
else
// 時間差小於 0 ,說明事件已經可以執行了,將秒和毫秒設為 0 (不阻塞)
if (tvp->tv_sec < 0) tvp->tv_sec = 0;
if (tvp->tv_usec < 0) tvp->tv_usec = 0;
} else else
}// 處理檔案事件,阻塞時間由 tvp 決定
numevents = aeapipoll(eventloop, tvp);
for (j = 0; j < numevents; j++)
// 寫事件
if (fe->mask & mask & ae_writable)
processed++;}}
/* check time events */
// 執行時間事件
if (flags & ae_time_events)
processed += processtimeevents(eventloop);
return processed; /* return the number of processed file/time events */
}
centos安裝redis server服務
進入 usr local mysql目錄make。然後再進入 usr local mysql src,接著cp redis server redis cli redis sentinel redis benchmark redis check aof usr local bin 建立配置檔案 mkd...
標準事件模型和IE事件模型
在瀏覽器解析事件的時候,有兩種觸發方式,一種叫做bubbling 冒泡 另外一種叫做capturing 捕獲 這裡不做過多解釋 這裡分析三種繫結事件模式 1 traditional module 傳統方式的事件模型即直接在dom元素上繫結事件處理器,例如 window.onload function...
事件(二) Jquery事件模型
與w3c標準事件api十分相似,除了名稱上的不同以外,唯一差別就是去掉了usecapture引數,並且去掉了事件名稱中的on字首。示例 如下 document bind ready function div bind mouseout function 與傳統的時間模型不同,jquery的事件名稱沒...