程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> 實例解析C++/CLI線程之多任務

實例解析C++/CLI線程之多任務

編輯:vc教程

簡介

從處理器的角度來看,線程是一個單獨的執行流程,每個線程都有各自的寄存器及堆棧上下文。通常來說,在中只有一個處理器或處理器只有一個核心時,運行時環境在一個時間片內只能執行一個線程,當線程未能獲取所需的資源時,線程的執行就會被中斷,且會一直等到相關操作的完成,如I/O;或者在線程用完它的處理器時間片時,也會被中斷下來等待。而處理器把執行流程從一個線程切換到另一個線程時,這稱為"上下文切換";當某個線程變為"阻塞"狀態,從而執行另一個線程時,系統有效地減少了處理器空閒時間,這稱為"多任務"。

當程序執行時,系統知道可以從磁盤上某處獲取相關的指令及靜態數據,程序會被分配到一組包含虛擬內存在內的地址空間,這個運行時上下文被稱為"進程"。然而,在一個進程可以運行之前,它必須擁有至少一個線程,也就是說,當一個進程被創建時,它自動被賦予了一個線程,這稱為"主線程"。但是話說回來,這個線程與之後這個進程所創建的線程相比,沒有任何不同之處,它只不過恰好是這個進程的第一個線程而已。一般來說,在程序的控制之下,進程內的線程數在運行時會有所變化,任何線程都可以創建其他的線程,但不管怎樣,線程不擁有它所創建的線程,所有進程內的線程都是作為一個整體屬於這個進程。

可把進程要完成的工作分成不同的"子任務",每一部分都由不同的線程來執行,這稱為"多線程"。進程內的每個線程共享同樣的地址空間與進程資源,當最後一個進程內的線程結束時,父進程就結束了。

為何進程內要有多個線程呢?如果進程只有一個線程,那麼它的執行流程是自上而下順序執行的;當線程阻塞,而又沒有其他的活動線程處於等待狀態時,系統就會進入空閒狀態;如果此時進程的子任務必須被順序地執行,那麼這種情況就不可避免,將花費大量的時間來等待。然而,絕大多數的進程都不是這樣的,試想有這樣一種情況,某個進程有多個選項,用戶可以選擇其中一些選項,由此產生的計算會使用內存或文件中的數據,並生成結果,如果能從中分出一些新的線程,那麼進程不必等待前一個計算的結果,就可以繼續接受新的計算請求。此外,通過指定線程的優先級,進程可只在更關鍵的線程阻塞時,才運行次關鍵的線程。

在有多個線程的情況下,某些線程可負責程序的主要工作,而另一個線程可用於處理鍵盤和鼠標的輸入。例如,用戶可能會覺得前一次請求並不是期望的動作,從而希望取消由前一次請求產生的那一個線程,這時就可在某個下拉菜單中進行選擇,由一個線程去終止另一個線程。

另一個例子就是打印假脫機程序,它的任務是保持打印機盡可能地滿載工作,並處理用戶的打印請求;如果這個程序必須要等到前一項打印工作完成,才能接受新請求的話,用戶可能會感到非常的不滿。當然,程序也可周期性地停下打印工作,來查看是否有新的未處理請求(這稱為"輪詢"),但是,如果沒有新請求,這將會非常浪費時間。另外,如果輪詢的間隔時間太長,對處理新請求,還會造成延時;如果間隔太短,那麼線程在輪詢上花費的時間又太多。那麼,為什麼不讓假脫機程序有兩個線程呢?一個用於將打印工作傳遞到打印機,而另一個用於處於用戶的請求,它們之間都相互獨立運行;而當一個線程工作完成時,它要麼結束自身,要麼進入休眠狀態。

當處理並發的執行線程時,必須要首先了解兩個重要的概念:原子性和重入性。一個原子變量或對象是作為一個整體被訪問的,甚至於在異步操作的情況下也是如此--訪問的是同一個變量或對象。舉例來講,如果一個線程正在更新一個原子變量或對象,而另一個線程在讀取其內容,此時來講,內容邏輯上的完整性是不可能被破壞的,所以,要麼讀取到舊值,要麼讀取到新值,而不會舊值新值各讀一部分。通常來說,能被原子性訪問的變量或對象,只是那些在硬件上能被原子性支持的類型,如字節(Byte)和字(Word)。C++/CLI中大多數的基本類型都確保具有原子性,剩下的類型也可被某種特定的實現支持原子性,但不能百分百保證。顯而易見,一個實現了x與y坐標對的Point對象,不具有原子性,對Point值的寫入,可能會被對其值的讀取中斷,結果就是,讀取到了一個新的x值和一個舊的y值,反之亦然;同樣地,數組也不可能被原子性地訪問。正是因為大多數的對象不能被原子性地訪問,所以必須使用一些同步形式來保證在某一時間,只有一個線程可操縱某個特定的對象。也正是因為此,C++/CLI分配給每一個對象、數據和類一個同步鎖。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved