服務器端編程常常須要構造高性能的IO模型,常見的IO模型有四種:html
(1)同步阻塞IO(Blocking IO):即傳統的IO模型。編程
(2)同步非阻塞IO(Non-blocking IO):默認建立的socket都是阻塞的,非阻塞IO要求socket被設置爲NONBLOCK。設計模式
(3)IO多路複用(IO Multiplexing):即經典的Reactor設計模式,有時也稱爲異步阻塞IO,Java中的Selector和Linux中的epoll都是這種模型。服務器
(4)異步IO(Asynchronous IO):即經典的Proactor設計模式,也稱爲異步非阻塞IO。markdown
同步和異步的概念描述的是用戶線程與內核的交互方式:多線程
同步是指用戶線程發起IO請求後須要等待或者輪詢內核IO操做完成後才能繼續執行;mvc
異步是指用戶線程發起IO請求後仍繼續執行,當內核IO操做完成後會通知用戶線程,或者調用用戶線程註冊的回調函數。異步
阻塞和非阻塞的概念描述的是用戶線程調用內核IO操做的方式:socket
阻塞是指IO操做須要完全完成後才返回到用戶空間;async
非阻塞是指IO操做被調用後當即返回給用戶一個狀態值,無需等到IO操做完全完成。
同步阻塞I/O模型是最簡單的I/O模型,用戶進程在進行I/O操做時被阻塞,以下圖所示:
在ASP.NET Core中沒有使用多線程或加入異步關鍵字的模型均爲同步阻塞I/O
public IActionResult Sync() { var start = DateTime.Now; Add(); return Json("start:"+start+"||| end:" + DateTime.Now); } void Add() { Thread.Sleep(2000); Console.WriteLine(DateTime.Now); }
在同步非阻塞整個IO請求的過程當中,雖然用戶線程每次發起IO請求後能夠當即返回,可是爲了等到數據,仍須要不斷地輪詢、重複請求,消耗了大量的CPU的資源。通常不多直接使用這種模型,而是在其餘IO模型中使用非阻塞IO這一特性
在ASP.NET Core 中可使用多線程來實現同步非阻塞,在以下代碼清單中能夠看到,使用多線程調用一個會自動休眠2秒的方法,主線程Sync
會先返回值,而不會阻塞。
public IActionResult Sync() { var thread = new Thread(new ThreadStart(this.Add)); thread.Start(); return Json(DateTime.Now); } void Add() { Thread.Sleep(2000); Console.WriteLine(DateTime.Now); }
而子線程因爲被阻塞了2秒,所以時間爲:
若是想在同步非阻塞的狀況下得到返回的數據,就須要輪詢,重複的對線程請求。代碼清單中使用while循環輪詢線程。
public IActionResult Sync() { short num = 10; var thread = new Thread(new ParameterizedThreadStart(this.Add)); thread.Start(num); while (thread.IsAlive) ; return Json(DateTime.Now + "result:" + result); } void Add(object num) { Thread.Sleep(2000); this.result =(short)num ; Console.WriteLine(DateTime.Now); }
真正的異步IO須要操做系統更強的支持。在異步IO模型中,當用戶線程收到通知時,數據已經被內核讀取完畢,並放在了用戶線程指定的緩衝區內,內核在IO完成後通知用戶線程直接使用便可。
public IActionResult Async() { var start = DateTime.Now; short num = 10; var result = Add(num).Result; return Json("start:"+ start +" end: " + DateTime.Now + " ||| result: " + result); } async Task<short> Add(short num) { await Task.Delay(2000); return ++num; }
關於異步的更詳細的使用可參看 http://www.cnblogs.com/vipyoumay/p/5663950.html
1.同步與異步關注的是消息通訊機制 (synchronous communication/ asynchronous communication)
所謂同步,就是在發出一個 調用
時,在沒有獲得結果以前,該調用
就不返回。可是一旦調用返回,就獲得返回值了。換句話說,就是由調用者
主動等待這個調用
的結果。而異步則是相反,調用
在發出以後,這個調用就直接返回了,因此沒有返回結果。換句話說,當一個異步過程調用發出後,調用者不會馬上獲得結果。而是在調用
發出後,被調用者
經過狀態、通知來通知調用者,或經過回調函數處理這個調用。
你打電話問書店老闆有沒有《分佈式系統》這本書,若是是同步通訊機制,書店老闆會說,你稍等,」我查一下",而後開始查啊查,等查好了(多是5秒,也多是一天)告訴你結果(返回結果)。而異步通訊機制,書店老闆直接告訴你我查一下啊,查好了打電話給你,而後直接掛電話了(不返回結果)。而後查好了,他會主動打電話給你。在這裏老闆經過「回電」這種方式來回調。
2. 阻塞與非阻塞關注的是程序在等待調用結果(消息,返回值)時的狀態.
阻塞調用是指調用結果返回以前,當前線程會被掛起。調用線程只有在獲得結果以後纔會返回。非阻塞調用指在不能馬上獲得結果以前,該調用不會阻塞當前線程。
你打電話問書店老闆有沒有《分佈式系統》這本書,你若是是阻塞式調用,你會一直把本身「掛起」,直到獲得這本書有沒有的結果,若是是非阻塞式調用,你無論老闆有沒有告訴你,你本身先一邊去玩了, 固然你也要偶爾過幾分鐘check一下老闆有沒有返回結果。在這裏阻塞與非阻塞與是否同步異步無關。跟老闆經過什麼方式回答你結果無關
【1】http://www.jianshu.com/p/77332a3b07b5
【2】http://kb.cnblogs.com/page/85931
【3】https://www.zhihu.com/question/19732473