標籤:

對於Tornado非同步庫使用的困惑?

小弟剛接觸Tornado.看到網上有一個帖子Blocking tasks in Tornado。是直接將同步操作轉成非同步的。如果這樣操作是可以的話,那還需要那些非同步的庫嗎?不是都可以加個裝飾符轉成非同步了嗎?


文章中提到的辦法就是個線程池,相當於把這個操作給放到另外一個線程中去運行,而主線程是不會等待在這裡阻塞的。

當然:你可以把所有請求都搞成這種模式,但是這樣得話:這就是個多線程程序了! 根本不是非同步模式。 多線程下你還要考慮線程安全性, cpu消耗等等。

而非同步不是這麼回事,非同步就一個線程,只是說這個線程內部不阻塞,其不是靠把操作交給另外的thread執行. 而是用諸如epoll的方式來實現的。 所以你會發現非同步庫都是針對網路io的幾乎,這是因為epoll這貨就是處理fd的呀。 網路io也是一種fd.


先謝邀!

tornado的非同步不是說加個decorator,就是非同步。加上 decorator 只是表示本方法是非同步的。但是方法裡面如果有同步代碼,一樣會阻塞住。

如果你想自動把同步變成非同步。建議看 gevent。gevent 有一個很屌但是也可能很坑人的 monkey.patch_all 方法。做的就是你說的這個事情。但是也不是所有的都生效。

文中的方法,只是簡單的利用threadpool來處理同步而已。並不是真正的非同步。


建議你花時間看看幾個概念。blocking和nonblocking講的是I/O,同步和非同步關注的是編程方法。談到nonblocking一定會談到poll/select/epoll的多路復用,這是另一個層面的事情。

所有的nonblocking的主線程或者說主進程就是一個while True:

while True:
epoll... 多路復用
for readable_fd do work
read data without block!!
deal with the data 如果你這裡有了block,死悄悄!!例如讀資料庫,訪問網路
for writeable_fd do work
write data without block!!

一般基於non-blocking的框架,都會把核心的ioloop暴漏出來,然後你在任何有I/O的地方都可以重用ioloop,註冊fd和回調的handler!

建議讀一下tornado的源碼,配合看點Linux編程的書。I/O本身東西不多,但是不覺得看看別人的回答你可以真正的理解。

別說你剛接觸,小弟第一天用tornado做的第一件事情就是讀完了ioloop和iostream...


這種編程很類似java 裡面的寫法,利用線程池維護一個請求並發數,非同步和非阻塞IO的概念不一樣。參見 asynchronous vs non-blocking 。

非同步執行只能說可以並行執行,並不是立即返回正確的結果,只是非同步執行後通過回調的方式將結果返回。IO 方面你看一下目前的幾種IO模型。


推薦閱讀:

tornado的AsyncHTTPClient和requests庫為什麼不關閉連接?
知乎為什麼要選擇用Tornado做為web開發框架,非同步非阻塞模式在此起到了作用?
知乎在Tornado開發中的Database Driver是什麼?
如何評價知乎開始將核心業務向 Go 技術棧遷移?

TAG:Tornado |