1. 程式人生 > >Thrift解讀(二)——TNonblockingServer I/O執行緒

Thrift解讀(二)——TNonblockingServer I/O執行緒

TNonblockingServer的I/O執行緒是TNonblockingIOThread物件。每個TNonblockingIOThread儲存服務的server指標,同時記錄監聽的套接字。他並不是真正的pthread,所以執行緒號是額外指定的,在構造方法中指定。

TNonblockingIOThread註冊兩類事件,一類是監聽套接字,回撥函式註冊為TNonblockingIOThread::listenHandler,上下文是server_指標;一類是監聽管道,用於通訊,回撥函式註冊為TNonblockingIOThread::notifyHandler,上下文是this指標。該管道非阻塞,並且不能為子程序複用。registerEvents用於註冊,notify用於通知,也就是向管道的寫入端寫入資料,內容是TConnection指標。每當一個Task執行完成,都要呼叫notify通知執行緒。另外,程式可以通過notify一個空指標,終止目標TNonblockingIOThread。

listenHandler是呼叫server_->workSocket方法,發起接收資料。

一旦任何管道有事件發生,libevent會啟用notifyHandler接收資料。如果接收到合法的TConnection指標,說明Task完成,呼叫TConnection->transition,將狀態機切換到“回送結果”。如果接收的結果是非法的資料,說明發生了錯誤,將故障的TNonBlockingIOThread終止(呼叫breakLoop方法)。如果接收到的結果是0,說明對端已經關閉了連線,即執行緒可能已經終止。如果沒有資料可以接收,那麼直接跳出這個回撥函式,下次有資料可以接收時,libevent會重新呼叫這個回撥函式。需要注意的是,儘管是非阻塞套管道套接字,僅僅接收到了資料是0,並不意味著一切正常而僅是沒有資料可以接收。如果是沒有資料可以接收但是一切正常,recv的結果應該是負值,並且errno會設定成EWOULDBLOCK或者EAGAIN。

breakLoop,如果是異常呼叫,程式直接退出(abort)。如果是正常呼叫,首先event_base_loopbreak,其次向目標TNonblockingIOThread傳送notify(NULL)

run是TNonblockingIOThread的基本執行緒體。先生成event_base,然後註冊監聽事件,即剛剛指明的兩個事件:管道和套接字。然後按需設定執行緒排程的優先順序(可以先忽略這段邏輯),event_base_loop。執行緒將阻塞在這裡,直到被event_base_loopbreak。這樣,一個長期執行的IO執行緒就啟動了。整個I/O流程開始由各種回撥處理,以及發起下一次流程。