同步:編程
含義:指兩個或兩個以上隨時間變化的量在變化過程當中保持必定的相對關係網絡
現象:有一個共同的時鐘,按來的順序一個一個處理框架
直觀感覺 :就是須要等候,效率低下異步
異步:異步編程
含義 :雙方不須要共同的時鐘,也就是接收方不知道發送方何時發送,因此在發送的信息中就要有提示接收方開始接收的信息,如開始位,同時在結束時有中止位函數
現象:沒有共同的時鐘,不考慮順序來了就處理tornado
直觀感覺:就是不用等了,效率高fetch
阻塞調用:spa
含義 : 阻塞調用是指調用結果返回以前,當前線程會被掛起(線程進入非可執行狀態,在這個狀態下,CPU不會給線程分配時間片,即線程暫停運行)。函數只有在獲得結果以後纔會返回線程
現象:讀套接字時沒有數據等數據來,寫套接字時寫不下了也一直等,等能寫下了往裏寫(套接字被寫滿的緣由不在本地,在於網絡另外一頭的套接字被寫滿了來不及讀出去,致使本地的套接字內容來發不出去堵住了)
直觀感覺:執着
非阻塞調用:
含義 :非阻塞調用是指沒有調用結果當即返回,當前線程不被掛起,能夠繼續作其它工做
現象:讀套接字時沒有數據,不等直接返回幹別的事去,寫套接字寫不下了也不寫了,直接返回幹別的事去
直觀感覺:勤奮
手動實現異步:
import threading import time #回調函數實現異步 #2.攜程實現異步 #返回數據的時候使用了不一樣的方式 # 在tornado裏面,把這些方式封裝成了裝飾器 #想使用異步的時候,加上這些裝飾器,就能夠實現異步 # epoll 加攜程實現異步 異步非阻塞框架,tornado def func(on_finish): def inner(on_finish): print('----start----') time.sleep(5) print('----end----') on_finish('hello world') #回調函數 # yield 'helloworld' #改爲攜程yield threading.Thread(target=inner,args=(on_finish,)).start() #改爲epoll #原來使用return返回數據,可是他有瓶頸,咱們使用一個函數來返回數據 def on_finish(result): print(result) func(on_finish) time.sleep(2) print('---------b---------')
函數執行結果以下:
異步編程:不少方法tornado 6.0版本已經不能使用,下面列舉兩種可用的
第一種:經過協程來實現異步(使用requests模塊)
第一步:安裝模塊
pip install futures
pip install requests
第二步:導入模塊
from tornado.concurrent import run_on_executor from concurrent.futures import ThreadPoolExecutor import requests
代碼以下:
class ReqHandler(RequestHandler): '''經過攜程來實現異步(使用requests模塊)''' executor = ThreadPoolExecutor() @tornado.gen.coroutine #攜程裝飾器 def get(self): response = yield self.func() self.write(response.text) @run_on_executor def func(self): res = requests.get('http://127.0.0.1:8000/sync?id=2') #異步的客戶端 return res
第二種:
官方推薦的方法:
class GenHandler(RequestHandler): '''當前版本官方推薦的異步案例''' @tornado.gen.coroutine #添加異步裝飾器 def get(self): client = AsyncHTTPClient() #異步的客戶端 response = yield client.fetch('http://127.0.0.1:8000/sync') self.write(response.body) #獲取請求參數