1. 程式人生 > >(轉)異步與非阻塞之間的區別(看到的最清晰的說明)

(轉)異步與非阻塞之間的區別(看到的最清晰的說明)

ron 啟動 同步與異步 我們 任務 nis pro 沖突 mission

Asynchronous I/O, or non-blocking I/O, is a form of input/output processing that permits other processing to continue before the transmission has finished

非阻塞不一定做到異步。非阻塞只是意味著方法調用不阻塞,但是通過事件通知的方式給調用線程一個機會去完成。它的邏輯是“等可以讀(寫)了告訴你”。這意味著工作的完成者仍然是調用者(線程)。

而異步不只是意味著方法調用不阻塞,它還意味著工作的完成已經轉移到別的線程。意思是,只要你把工作交給了我,工作就“交”給了我。也許你會傳個回調函數給我,但是函數的調用仍然是由“我”來完成的。你在發出調用以後,不再需要任何的工作。調用發出了,你的工作就完成了。我的工作開始了。工作轉移到我這邊。我是下一步。你可以接下去做別的工作。

它的邏輯是“我做完了 告訴/不告訴 你”。它與非阻塞的區別在於:“做完了”。能力來源當然是後臺的線程機制。

這種機制,使用起來其實需要相當小心,因為它在現有程序以外自作主張地新開了線程。這顯然將影響整個的運行時計劃。API不應該擁有執行自己的能力,它們只應該擁有一種能力那就是:被調用!

但是無論如何,它提供了一種真正可能的異步工作模式:你做你的事情,我做我的事情。我們通過一定的通信手段進行合作。合作流程非常清晰。

如果說在異步IO以前,所有的程序必須自行處理IO問題。那麽,有了異步IO,程序就徹底從IO的負擔中解脫出來了:1,I/O工作被徹底從原有線程中分離出去。原有線程在I/O工作中除了把I/O目的告訴異步I/O API,它不需要做任何額外的工作(為了完成原有的I/O任務);2,I/O工作在獨立的線程中完成,不管它有或可能產生任何問題,這種問題也不可能POP UP到調用者線程即代碼中去。調用者線程甚至不需要去捕捉任何I/O異常!

問題是:I/O在應用程序中究竟處於或應該處於什麽地位?意思是,它是一級公民,還是二級公民?因為為I/O工作啟動單獨的線程顯然意味著它已經處於與程序的其它部分同等重要的地位。

這個問題的核心其實是:對應於兩個級別,I/O其實對應的只是兩種工作方式:1,被調用;2,被升華成線程。

兩者的區別是什麽?

把處理器虛擬化的話,調用與線程其實都只不過是處理器所執行的一些代碼而已。不管是調用還是線程,其實都是發生在同一個地方:進程內存空間。調用是一種代碼協作手段,線程是另一種代碼協作手段。只不過第一,線程中的個體,比調用中的個體,傳統上的看法,級別要更“高”一些。因為調用者本身其實也是被線程所調用的。因此,一切都可以被看成是被線程所調用的。但是現在I/O變成了單獨的線程,它搖身一變,從被調用的代碼變成了調用的主宰者。第二,調用是一種縱向的協作模式,線程是一種橫向的協作模式。

從工作內容的特性上面看,I/O的確是一種與眾不同的工作。它被分出來,是正確的選擇。事實上,在進行線程設計的時候,所根據的一個主要劃分原則就是工作內容的不同。比如,UI線程經常是與其它線程獨立的。

。。。

該如何利用線程?線程到底是什麽東西?最終的一切,我覺得還是為了本地性能的最大化。當然有時候性能最大化跟用戶目標會有沖突,但基本上,在大部分時候,如果達到了性能的最大化,也就達到了服務性能的提高。也就達到了用戶體驗的提高。

目前還沒有看到這方面的沖突。


還看到一個簡明扼要闡述區別的說明:
同步與異步是對應的,它們是線程之間的關系,兩個線程之間要麽是同步的,要麽是異步的。

阻塞與非阻塞是對同一個線程來說的,在某個時刻,線程要麽處於阻塞,要麽處於非阻塞。

阻塞是使用同步機制的結果,非阻塞則是使用異步機制的結果。(不是存在同步非阻塞和異步阻塞這兩種情況嗎?

(轉)異步與非阻塞之間的區別(看到的最清晰的說明)