1. 程式人生 > >tornado原始碼分析(二)之iostream

tornado原始碼分析(二)之iostream

在事件驅動模型中,所有任務都是以某個事件的回撥函式的方式新增至事件迴圈中的,如:HTTPServer要從socket中讀取客戶端傳送的request訊息,就必須將該socket新增至ioloop中,並設定回掉函式,在回掉函式中從socket中讀取資料,並且檢查request訊息是否全部接收到了,如果沒有接收完則需要儲存當前的資料,直到讀去完為止

iostream的作用是讓各元件,不需要與ioloop直接互動,iostream幫助各元件將socket新增至ioloop,並設定回掉函式,讀取並儲存資料,直到所有資料都接收完為止。有了iostream,httpserver就只需要通過iostream讀取資料即可,而不需關心非同步讀取資料的過程。

iostream同樣可以看作一個事件迴圈,它提供兩類事件:讀完成、寫完成。

iostream是基於ioloop的,建立iostream時必需給定一個檔案描述符,iostream將該檔案描述符新增至ioloop的io事件中,並設定回撥函式(_handle_events),在回掉函式中判斷檔案描述符是可讀,還是可寫。

當該檔案描述符可讀時,iostream從檔案描述符中讀出資料,並存至自己的資料緩衝中。每次讀取到新的資料後,iostream都檢查是否觸發了自己管理的事件,如:是否讀到了某一特定的資料(由read_until、read_until_regex等介面註冊),是否讀到了足夠多的資料(由read_bytes註冊)等,如果觸發了事件,則呼叫對應事件的回撥函式(非同步事件為future,設定future的result即可呼叫非同步事件的回撥函式)。

當檔案描述符可寫時,首先iostream從寫緩衝中,讀取足量的資料,寫入至檔案描述符中。其次能進入當前邏輯,說明上一次寫入檔案描述符的資料已經發送出去了,此時需要逐個檢查註冊的寫事件是否已經完成(各寫事件中儲存了自己關注的寫緩衝區的位置,通過檢查該位置判斷該事件的資料是否已經發送),如果完成則呼叫事件的回撥函式。

iostream提供了非常多的非同步讀取資料的介面,read_until,read_bytes,read_unitl_regex等,iostream在同一時間內只能存在一個讀事件。

iostream通過write介面新增非同步寫事件,可以同時存在多個(只要iostream的寫緩衝區足夠)。每次新增時建立一個future,並且記錄該事件的要寫的資料在寫緩衝區中的位置(加入資料後iostream的_total_write_index),每次有資料傳送後根據該位置資訊判斷是否結束(iostream的_total_write_done_index是否超過了事件的資料的位置)。 

 原始碼參考:tornado.iostream.IOStream