1. 程式人生 > >並發 並行 同步 異步 多線程的區別

並發 並行 同步 異步 多線程的區別

最大 圖形 死鎖 消耗cpu 概念 都是 通知 貴的 長時間

一、異步和多線程有什麽區別?其實,異步是目的,而多線程是實現這個目的的方法。異步是說,A發起一個操作後(一般都是比較耗時的操作,如果不耗時的操作就沒有必要異步了),可以繼續自顧自的處理它自己的事兒,不用幹等著這個耗時操作返回。.Net中的這種異步編程模型,就簡化了多線程編程,我們甚至都不用去關心Thread類,就可以做一個異步操作出來。


二、隨著擁有多個硬線程CPU(超線程、雙核)的普及,多線程和異步操作等並發程序設計方法也受到了更多的關註和討論。本文主要是想探討一下如何使用並發來最大化程序的性能。

  多線程和異步操作的異同

  多線程和異步操作兩者都可以達到避免調用線程阻塞的目的,從而提高軟件的可響應性。甚至有些時候我們就認為多線程和異步操作是等同的概念。但是,多線程和異步操作還是有一些區別的。而這些區別造成了使用多線程和異步操作的時機的區別。

  異步操作的本質

  所有的程序最終都會由計算機硬件來執行,所以為了更好的理解異步操作的本質,我們有必要了解一下它的硬件基礎。 熟悉電腦硬件的朋友肯定對DMA這個詞不陌生,硬盤、光驅的技術規格中都有明確DMA的模式指標,其實網卡、聲卡、顯卡也是有DMA功能的。DMA就是直 接內存訪問的意思,也就是說,擁有DMA功能的硬件在和內存進行數據交換的時候可以不消耗CPU資源。只要CPU在發起數據傳輸時發送一個指令,硬件就開 始自己和內存交換數據,在傳輸完成之後硬件會觸發一個中斷來通知操作完成。這些無須消耗CPU時間的I/O操作正是異步操作的硬件基礎。所以即使在DOS 這樣的單進程(而且無線程概念)系統中也同樣可以發起異步的DMA操作。

  線程的本質

  線程不是一個計算機硬件的功能,而是操作系統提供的一種邏輯功能,線程本質上是進程中一段並發運行的代碼,所以線程需要操作系統投入CPU資源來運行和調度。

  異步操作的優缺點

  因為異步操作無須額外的線程負擔,並且使用回調的方式進行處理,在設計良好的情況下,處理函數可以不必使用共享變量(即使無法完全不用,最起碼可以減少 共享變量的數量),減少了死鎖的可能。當然異步操作也並非完美無暇。編寫異步操作的復雜程度較高,程序主要使用回調方式進行處理,與普通人的思維方式有些 初入,而且難以調試。

  多線程的優缺點

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

  適用範圍

  在了解了線程與異步操作各自的優缺點之後,我們可以來探討一下線程和異步的合理用途。我認為:當需要執行I/O操作時,使用異步操作比使用線程+同步 I/O操作更合適。I/O操作不僅包括了直接的文件、網絡的讀寫,還包括數據庫操作、Web Service、HttpRequest以及.net Remoting等跨進程的調用。

  而線程的適用範圍則是那種需要長時間CPU運算的場合,例如耗時較長的圖形處理和算法執行。但是往 往由於使用線程編程的簡單和符合習慣,所以很多朋友往往會使用線程來執行耗時較長的I/O操作。這樣在只有少數幾個並發操作的時候還無傷大雅,如果需要處 理大量的並發操作時就不合適了。

  異步調用與多線程

異步調用並不是要減少線程的開銷, 它的主要目的是讓調用方法的主線程不需要同步等待在這個函數調用上, 從而可以讓主線程繼續執行它下面的代碼.與此同時, 系統會通過從ThreadPool中取一個線程來執行,幫助我們將我們要寫/讀的數據發送到網卡.由於不需要我們等待, 我們等於同時做了兩件事情. 這個效果跟自己另外啟動一個線程來執行等待方式的寫操作是一樣的.但是, 異步線程可以利用操作系統/.Net的線程池, 系統可以根據吞吐量動態的管理線程池的大小.

=======================================================================
異步與多線程,從辯證關系上來看,異步和多線程並不時一個同等關系,異步是目的,多線程只是我們實現異步的一個手段.什麽是異步:異步是當一個調用請求發送給被調用者,而調用者不用等待其結果的返回.實現異步可以采用多線程技術或則交給另外的進程來處理
=========================================================================
線程池的實現方法與線程是不一樣的.初始化時在線程池裏的線程為0.當進程需要一個線程時,創建一個線程,由此線程執行用戶的方法.需要註意的是,此線程執行完後並不立即銷毀,而是掛起等待,如果有其他方法需要執行,回喚醒進行處理.只有當它等到40秒(沒有官方記錄,有可能是其它數字)還沒有任務執行時才喚醒自己,並銷毀自己,釋放資源.當然,如果線程池中的線程不夠處理任務時,會再次創建一個新線程進行執行.

異步有的時候用普通的線程,有的時候用系統的異步調用功能。有一些IO操作也是異步的,但是未必需要一個線程來運行。例如:硬件是有DMA功能的,在調用DMA傳輸數據的時候,CPU是不需要執行處理的,只需要發起傳輸和等待傳輸結束即可。具體到.net平臺,比如Socket的BeginSend,如果是運行在Windows 2000以後的平臺,在底層就會調用異步的完成端口來發送。

.Net中的異步執行其實使用的是異步委托。異步委托將要執行的方法提交到.net的線程池,由線程池中的線程來執行異步方法。

異步執行也得執行,不在當前線程執行,當然得去另外一個線程執行。異步通常用系統線程池的線程,通常情況下性能好些。(因為可以多次利用,申請時不需要重新申請一個線程,只需要從池裏取就行了。)異步是一種效果,多線程是一種具體技術。可以說,用“多線程”實現“異步”。

異步和多線程是兩個不同的概念,不能這樣比較.異步請求一般用在IO等耗時操作上,他的好處是函數調用立即返回,相應的工作線程立即返還給系統以供重用。由於系統的線程資源是非常寶貴的,通常有一定的數目限制,如.net默認是25。若使用異步方式,用這些固定數目的線程在固定的時間內就可以服務更多的請求,而如果用同步方式,那麽每個請求都自始至終占用這一個線程,服務器可以同時服務的請求數就少了。當異步操作執行完成後,系統會從可用線程中選取一個執行回調程序,這時的這個線程可能是剛開始發出請求的那個線程,也可能是其他的線程,因為系統選取線程是隨機的事情,所以不能說絕對不是剛開始的那個線程。多線程是用來並發的執行多個任務。

不過有個問題,異步有時優先級比主線程還高。這個特點和多線程不同。

並發 並行 同步 異步 多線程的區別