redis的事件驅動模組負責處理檔案和定時器兩種任務。
下面是幾個函式指標
typedef
void
aefileproc
(struct aeeventloop *eventloop,
int fd,
void
*clientdata,
int mask)
;typedef
intaetimeproc
(struct aeeventloop *eventloop,
long
long id,
void
*clientdata)
;typedef
void
aeeventfinalizerproc
(struct aeeventloop *eventloop,
void
*clientdata)
;
下面是檔案相關的結構體
struct aefileevent aefileevent;
下面是定時器結構體
struct aetimeevent aetimeevent;
下面是事件迴圈的核心結構體
struct aeeventloop aeeventloop;
下面先看一下一些基礎函式,然後再分析具體流程。
aeeventloop *
aecreateeventloop
(void
)
2.1 新建乙個檔案相關的結構體
int
aecreatefileevent
(aeeventloop *eventloop,
int fd,
int mask,
aefileproc *proc,
void
*clientdata,
aeeventfinalizerproc *finalizerproc)
2.2 刪除乙個檔案相關的結構體
// 刪除某個節點(fd和mask等於入參的節點)
void
aedeletefileevent
(aeeventloop *eventloop,
int fd,
int mask)
prev = fe;
fe = fe-
>next;
}}
long
long
aecreatetimeevent
(aeeventloop *eventloop,
long
long milliseconds,
aetimeproc *proc,
void
*clientdata,
aeeventfinalizerproc *finalizerproc)
3.1 時間相關的函式
// 獲取當前時間,秒和毫秒
static
void
aegettime
(long
*seconds,
long
*milliseconds)
static
void
aeaddmillisecondstonow
(long
long milliseconds,
long
*sec,
long
*ms)
// 返回絕對時間的秒和毫秒
*sec = when_sec;
*ms = when_ms;
}
// 刪除乙個timeevent節點
intaedeletetimeevent
(aeeventloop *eventloop,
long
long id)
prev = te;
te = te-
>next;
}return ae_err;
/* no event with the specified id found */
}
3.3 查詢最快到期的定時器節點
// 找出最快到期的節點
static aetimeevent *
aesearchnearesttimer
(aeeventloop *eventloop)
return nearest;
}
最後來看一下事件處理的邏輯,入口函式是
void
aemain
(aeeventloop *eventloop)
該函式由redis初始化時,main函式呼叫。這個版本使用的多路復用函式是select
int
aeprocessevents
(aeeventloop *eventloop,
int flags)
}// 有檔案事件需要處理,或者有time事件並且沒有設定ae_dont_wait(設定的話就不會進入select定時阻塞)標記
if(numfd ||
((flags & ae_time_events)&&!
(flags & ae_dont_wait)))
; */
struct timeval tv,
*tvp;
// 有time事件需要處理,並且沒有設定ae_dont_wait標記,則select可能會定時阻塞(如果有time節點的話)
if(flags & ae_time_events &&
!(flags & ae_dont_wait)
)// 找出最快到期的節點
shortest =
aesearchnearesttimer
(eventloop)
;// 有待到期的time節點
if(shortest)
else
}else
else
}
retval =
select
(maxfd+1,
&rfds,
&wfds,
&efds, tvp);if
(retval >0)
else}}
}// 處理time事件
if(flags & ae_time_events)
// 獲取當前時間
aegettime
(&now_sec,
&now_ms)
;// 到期了
if(now_sec > te-
>when_sec ||
(now_sec == te-
>when_sec && now_ms >= te-
>when_ms)
)else
te = eventloop-
>timeeventhead;
}else}}
// 處理的事件個數
return processed;
/* return the number of processed file/time events */
}
redis0 1原始碼解析之字典
字典也叫雜湊表。看一下redis中的實現。下面是資料結構關係圖。redis中,雜湊表的設計思想是,申請乙個指標陣列,然後每個元素指向乙個鍊錶用來儲存資料 即鏈位址法 申請乙個表示字典的資料結構 dict dictcreate dicttype type,void privdataptr 初始化字典資...
redis0 1原始碼解析之鍊錶
分析 之前先看看鍊錶的資料結構。新建乙個煉表頭結點 list listcreate void 釋放乙個鍊錶 void listrelease list list 釋放鍊錶記憶體 zfree list 3 插入乙個節點 支援頭插和尾插 給鍊錶新增乙個節點,頭插法 list listaddnodehea...
Redis原始碼分析之事務
redis是通過multi discard exec watch四個命令來實現事務的。事務提供了一種將多個命令打包,然後一次性並順序的執行所有命令的機制,並且事務在執行中不會主動中斷,伺服器只有在事務執行完後,才會繼續執行其他客戶端的請求。下面是乙個事務的例子 redis multi okredis...