redis0 1原始碼解析之事件驅動

2021-10-06 10:49:05 字數 3755 閱讀 9900

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...