異步編程與多線程編程的聯繫和區別

參考網址:https://blog.csdn.net/qq_27825451/article/details/78853119python

  

一、異步編程與多線程的區別算法

共同點:異步和多線程二者均可以達到避免調用線程阻塞的目的,從而提升軟件的可響應性數據庫

不一樣點:編程

        (1)線程不是一個計算機硬件的功能,而是操做系統提供的一種邏輯功能,線程本質上是進程中一段併發運行的代碼,因此線程須要操做系統投入CPU資源來運行和調度。網絡

                 多線程的優勢很明顯,線程中的處理程序依然是順序執行,符合普通人的思惟習慣,因此編程簡單。可是多線程的缺點也一樣明顯,線              程的使用(濫用)會給系統帶來上下文切換的額外負擔。而且線程間的共享變量可能形成死鎖的出現多線程

      (2)異步操做無須額外的線程負擔,而且使用回調的方式進行處理,在設計良好的狀況下,處理函數能夠沒必要使用共享變量(即便沒法完                全不用,最起碼能夠減小 共享變量的數量),減小了死鎖的可能。固然異步操做也並不是完美無暇。編寫異步操做的複雜程度較高,程序              主要使用回調方式進行處理,與普通人的思惟方式有些 初入,並且難以調試。併發

        這裏有一個疑問。異步操做沒有建立新的線程,咱們必定會想,好比有一個文件操做,大量數據從硬盤上讀取,若使用單線程的同步操做天然要等待會很長時間,可是若使用異步操做的話,咱們讓數據讀取異步進行,二線程在數據讀取期間去幹其餘的事情,咱們會想,這怎麼行呢,異步沒有建立其餘的線程,一個線程去幹其餘的事情去了,那數據的讀取異步執行是去由誰完成的呢?實際上,本質是這樣的。異步

        熟悉電腦硬件的朋友確定對DMA這個詞不陌生,硬盤、光驅的技術規格中都有明確DMA的模式指標,其實網卡、聲卡、顯卡也是有DMA功能的。DMA就是直 接內存訪問的意思,也就是說,擁有DMA功能的硬件在和內存進行數據交換的時候能夠不消耗CPU資源。只要CPU在發起數據傳輸時發送一個指令,硬件就開 始本身和內存交換數據,在傳輸完成以後硬件會觸發一箇中斷來通知操做完成。這些無須消耗CPU時間的I/O操做正是異步操做的硬件基礎。因此即便在DOS 這樣的單進程(並且無線程概念)系統中也一樣能夠發起異步的DMA操做。async

       即CPU在數據的長時間讀取過程當中 ,只須要作兩件事,第一發布指令,開始數據交換;第二,交換結束,獲得指令,CPU再進行後續操做。而中間讀取數據漫長的等待過程,CPU自己就不須要參與,順序執行就是我不參與可是我要乾等着,效率低下;異步執行就是,我不須要參與那我就去幹其餘事情去了,你作完了再通知我就能夠了(回調)。異步編程

       可是你想一下,若是有一些異步操做必需要CPU的參與才能完成呢,即我開始的那個線程是走不開的,這該怎麼辦呢,在.NET中,有線程池去完成,線程池會高效率的開啓一個新的線程去完成異步操做,在python中這是系統本身去安排的,無需人工干預,這就比本身建立不少的線程更加高效。

總結:

       (1)「多線程」,第1、最大的問題在於線程自己的調度和運行須要不少時間,所以不建議本身建立太大量的線程;第2、共享資源的調度比較難,涉及到死鎖,上鎖等相關的概念。

       (2)「異步」 ,異步最大的問題在於「回調」,這增長了軟件設計上的難度。

在實際設計時,咱們能夠將二者結合起來:

       (1)當須要執行I/O操做時,使用異步操做比使用線程+同步 I/O操做更合適。I/O操做不只包括了直接的文件、網絡的讀寫,還包括數據庫操做、Web Service、HttpRequest以及.net Remoting等跨進程的調用。異步特別適用於大多數IO密集型的應用程序。
       (2)而線程的適用範圍則是那種須要長時間CPU運算的場合,例如耗時較長的圖形處理和算法執行。可是往 往因爲使用線程編程的簡單和符合習慣,因此不少朋友每每會使用線程來執行耗時較長的I/O操做。這樣在只有少數幾個併發操做的時候還無傷大雅,若是須要處 理大量的併發操做時就不合適了。

二、在多線程編程和異步編程上的進步(以.NET和python語言爲例進行說明)

       多線程最大的問題在於「線程的調度」,而在.NET中引入了線程池的概念,避免人爲建立多餘線程,讓系統進行分配;而Python語言中的多線程編程效率一直飽受詬病,所以python不多使用多線程,通常使用「協程」,後面會講到。

      異步最大的問題在於「回調」,.NET隨着版本的升級,從多任務編程,到後面使用await-async關鍵字的提高,讓人更加方便,不用注意到複雜的回調問題,用同步的思惟方式進行異步編程。python從3.4版本開始也開始使用協程和時間循環機制,從yield和yield from 語句中受到啓發,解決了「回調問題」,而在python3.5版本中,也是使用了await-async關鍵字,進一步簡化了編程。在這一方面,python和.NET有不少類似之處。(詳細案例會在後面文章中展現)

相關文章
相關標籤/搜索