目錄 英文:Thread
每個正在係統上運行的程序都是一個進程。每個進程包含一到多個綫程。進程也可能是整個程序或者是部分程序的動態執行。綫程是一組指令的集合,或者是程序的特殊段,它可以在程序裏獨立執行。也可以把它理解為代碼運行的上下文。所以綫程基本上是輕量級的進程,它負責在單個程序裏執行多任務。通常由操作係統負責多個綫程的調度和執行。
綫程是程序中一個單一的順序控製流程.在單個程序中同時運行多個綫程完成不同的工作,稱為多綫程 .
綫程和進程的區別在於,子進程和父進程有不同的代碼和數據空間,而多個綫程則共享數據空間,每個綫程有自己的執行堆棧和程序計數器為其執行上下文.多綫程 主要是為了節約CPU時間,發揮利用,根據具體情況而定. 綫程的運行中需要使用計算機的內存資源和CPU。 多綫程 是為了同步完成多項任務,不是為了提高運行效率,而是為了提高資源使用效率來提高係統的效率。綫程是在同一時間需要完成多項任務的時候實現的。
使用綫程的好處有以下幾點:
·使用綫程可以把占據長時間的程序中的任務放到後臺去處理
·用戶界面可以更加吸引人,這樣比如用戶點擊了一個按鈕去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度
·程序的運行速度可能加快
·在一些等待的任務實現上如用戶輸入、文件讀寫和網絡收發數據等,綫程就比較有用了。在這種情況下可以釋放一些珍貴的資源如內存占用等等。
還有其他很多使用多綫程 的好處,這裏就不一一說明了。
一些綫程模型的背景
可以重點討論一下在Win32環境中常用的一些模型。
·單綫程模型
在這種綫程模型中,一個進程中衹能有一個綫程,剩下的進程必須等待當前的綫程執行完。這種模型的缺點在於係統完成一個很小的任務都必須占用很長的時間。
·塊綫程模型(單綫程多塊模型STA)
這種模型裏,一個程序裏可能會包含多個執行的綫程。在這裏,每個綫程被分為進程裏一個單獨的塊。每個進程可以含有多個塊,可以共享多個塊中的數據。程序規定了每個塊中綫程的執行時間。所有的請求通過Windows消息隊列進行串行化,這樣保證了每個時刻衹能訪問一個塊,因而衹有一個單獨的進程可以在某一個時刻得到執行。這種模型比單綫程模型的好處在於,可以響應同一時刻的多個用戶請求的任務而不衹是單個用戶請求。但它的性能還不是很好,因為它使用了串行化的綫程模型,任務是一個接一個得到執行的。
·多綫程 塊模型(自由綫程塊模型)
多綫程 塊模型(MTA)在每個進程裏衹有一個塊而不是多個塊。這單個塊控製着多個綫程而不是單個綫程。這裏不需要消息隊列,因為所有的綫程都是相同的塊的一個部分,並且可以共享。這樣的程序比單綫程模型和STA的執行速度都要塊,因為降低了係統的負載,因而可以優化來減少係統idle的時間。這些應用程序一般比較復雜,因為程序員必須提供綫程同步以保證綫程不會並發的請求相同的資源,因而導致競爭情況的發生。這裏有必要提供一個鎖機製。但是這樣也許會導致係統死鎖的發生。
進程和綫程都是操作係統的概念。進程是應用程序的執行實例,每個進程是由私有的虛擬地址空間、代碼、數據和其它各種係統資源組成,進程在運行過程中創建的資源隨着進程的終止而被銷毀,所使用的係統資源在進程終止時被釋放或關閉。
綫程是進程內部的一個執行單元。係統創建好進程後,實際上就啓動執行了該進程的主執行綫程,主執行綫程以函數地址形式,比如說main或WinMain函數,將程序的啓動點提供給Windows係統。主執行綫程終止了,進程也就隨之終止。
每一個進程至少有一個主執行綫程,它無需由用戶去主動創建,是由係統自動創建的。用戶根據需要在應用程序中創建其它綫程,多個綫程並發地運行於同一個進程中。一個進程中的所有綫程都在該進程的虛擬地址空間中,共同使用這些虛擬地址空間、全局變量和係統資源,所以綫程間的通訊非常方便,多綫程 技術的應用也較為廣泛。多綫程 可以實現並行處理,避免了某項任務長時間占用CPU時間。要說明的一點是,目前大多數的計算機都是單處理器(CPU)的,為了運行所有這些綫程,操作係統為每個獨立綫程安排一些CPU時間,操作係統以輪換方式嚮綫程提供時間片,這就給人一種假象,好象這些綫程都在同時運行。由此可見,如果兩個非常活躍的綫程為了搶奪對CPU的控製權,在綫程切換時會消耗很多的CPU資源,反而會降低係統的性能。這一點在多綫程 編程時應該註意。Win32 SDK函數支持進行多綫程 的程序設計,並提供了操作係統原理中的各種同步、互斥和臨界區等操作。Visual C++ 6.0中,使用MFC類庫也實現了多綫程 的程序設計,使得多綫程 編程更加方便。 在本質上和結構來說,.NET是一個多綫程 的環境。有兩種主要的多綫程 方法是.NET所提倡的:使用ThreadStart來開始你自己的進程,直接的(使用ThreadPool.QueueUserWorkItem)或者間接的(比如Stream.BeginRead,或者調用BeginInvoke)使用ThreadPool類。一般來說,你可以"手動"為長時間運行的任務創建一個新的綫程,另外對於短時間運行的任務尤其是經常需要開始的那些,進程池是一個非常好的選擇。進程池可以同時運行多個任務,還可以使用框架類。對於資源緊缺需要進行同步的情況來說,它可以限製某一時刻衹允許一個綫程訪問資源。這種情況可以視為給綫程實現了鎖機製。綫程的基類是System.Threading。所有綫程通過CLI來進行管理。
·創建綫程:
創建一個新的Thread對象的實例。Thread的構造函數接受一個參數:
Thread DummyThread = new Thread( new ThreadStart(dummyFunction) );
·執行綫程:
使用Threading命名空間裏的start方法來運行綫程:
DummyThread.Start ();
·組合綫程:
經常會出現需要組合多個綫程的情況,就是當某個綫程需要其他綫程的結束來完成自己的任務。假設DummyThread必須等待DummyPriorityThread來完成自己的任務,衹需要這樣做:
DummyPriorityThread.Join() ;
·暫停綫程:
使得綫程暫停給定的秒
DummyPriorityThread.Sleep(<Time in Second>);
·中止綫程:
如果需要中止綫程可以使用如下的代碼:
DummyPriorityThread.Abort();
·同步
經常會遇到需要在綫程間進行同步的情況,下面的代碼給出了一些方法:
using System;
using System.Threading;
namespace SynchronizationThreadsExample
{
class SynchronizationThreadsExample
{
private int counter = 0;
static void Main( )
{
SynchronizationThreadsExample STE = new SynchronizationThreadsExample();
STE.ThreadFunction( );
}
public void ThreadFunction ( )
{
Thread DummyThread = new Thread( new ThreadStart(SomeFunction)) ;
DummyThread.IsBackground=true;
DummyThread.Name = "First Thread";
DummyThread.Start( );
Console.WriteLine("Started thread ", DummyThread.Name);
Thread DummyPriorityThread = new Thread( new ThreadStart(SomeFunction) );
DummyPriorityThread.IsBackground=true;
DummyPriorityThread.Name = "Second Thread";
DummyPriorityThread.Start( );
Console.WriteLine("Started thread ", DummyPriorityThread.Name);
DummyThread.Join( );
DummyPriorityThread.Join( );
}
public void SomeFunction( )
{
try
{
while (counter < 10)
{
int tempCounter = counter;
tempCounter ++;
Thread.Sleep(1);
counter = tempCounter;
Console.WriteLine( "Thread . SomeFunction: "+Thread.CurrentThread.Name+counter);
}
}
catch (ThreadInterruptedException Ex)
{
Console.WriteLine( "Exception in thread "+Thread.CurrentThread.Name);
}
finally
{
Console.WriteLine( "Thread Exiting. "+Thread.CurrentThread.Name);
}
}
}
}
·使用Interlock
C#提供了一個特殊的類叫做interlocked,就是提供了鎖機製的實現,可以加入如下的代碼實現鎖機製:
Interlocked.SomeFunction (ref counter);
·使用鎖
這是為了鎖定代碼關鍵區域以進行同步,鎖定代碼如下:
lock (this){ Some statements ;}
·使用Monitor
當有需要進行綫程管理的時候可以使用:
Monitor.Enter(this);
其他也有一些方法進行管理,這裏就不一一提及了。
綫程的缺點
綫程自然也有缺點,以下列出了一些:
·如果有大量的綫程,會影響性能,因為操作係統需要在他們之間切換;
·更多的綫程需要更多的內存空間
·綫程會給程序帶來更多的bug,因此要小心使用
·綫程的中止需要考慮其對程序運行的影響
·通常塊模型數據是在多個綫程間共享的,需要一個合適的鎖係統替換掉數據共享
參考鏈接:
http://hi.baidu.com/ce%5Fken/blog/item/c7e7ebc40fe265ca39db49a7.html
http://hi.baidu.com/ce%5Fken/blog/item/70c5670f62592a2b6159f348.html Java對多綫程 的支持是非常強大的,他屏蔽掉了許多的技術細節,讓我們可以輕鬆的開發多綫程 的應用程序。
Java裏面實現多綫程 ,有2個方法
1 繼承 Thread類,比如
class MyThread extends Thread {
public void run() {
// 這裏寫上綫程的內容
}
public static void main(String[] args) {
// 使用這個方法啓動一個綫程
new MyThread().start();
}
}
2 實現 Runnable接口
class MyThread implements Runnable{
public void run() {
// 這裏寫上綫程的內容
}
public static void main(String[] args) {
// 使用這個方法啓動一個綫程
new Thread(new MyThread()).start();
}
}
一般鼓勵使用第二種方法,因為Java裏面衹允許單一繼承,但允許實現多個接口。第二個方法更加靈活。 一個采用了多綫程 技術的應用程序可以更好地利用係統資源。其主要優勢在於充分利用了CPU的空閑時間片,可以用盡可能少的時間來對用戶的要求做出響應,使得進程的整體運行效率得到較大提高,同時增強了應用程序的靈活性。更為重要的是,由於同一進程的所有綫程是共享同一內存,所以不需要特殊的數據傳送機製,不需要建立共享存儲區或共享文件,從而使得不同任務之間的協調操作與運行、數據的交互、資源的分配等問題更加易於解决。 在多綫程 應用中,考慮不同綫程之間的數據同步和防止死鎖。當兩個或多個綫程之間同時等待對方釋放資源的時候就會形成綫程之間的死鎖。為了防止死鎖的發生,需要通過同步來實現綫程安全。在Visual Basic.NET中提供了三種方法來完成綫程的同步。
(1)代碼域同步:使用Monitor類可以同步靜態/實例化的方法的全部代碼或者部分代碼段。
(2)手工同步:可以使用不同的同步類(諸如WaitHandle, Mutex, ReaderWriterLock, ManualResetEvent, AutoResetEvent 和Interlocked等)創建自己的同步機製。這種同步方式要求你自己手動的為不同的域和方法同步,這種同步方式也可以用於進程間的同步和解除由於對共享資源的等待而造成的死鎖。
(3)上下文同步:使用SynchronizationAttribute為ContextBoundObject對象創建簡單的,自動的同步。這種同步方式僅用於實例化的方法和域的同步。所有在同一個上下文域的對象共享同一個鎖。
雖然多綫程 能給大傢帶來好處,但是也有不少問題需要解决。例如,對於像磁盤驅動器這樣獨占性係統資源,由於綫程可以執行進程的任何代碼段,且綫程的運行是由係統調度自動完成的,具有一定的不確定性,因此就有可能出現兩個綫程同時對磁盤驅動器進行操作,從而出現操作錯誤;又例如,對於銀行係統的計算機來說,可能使用一個綫程來更新其用戶數據庫,而用另外一個綫程來讀取數據庫以響應儲戶的需要,極有可能讀數據庫的綫程讀取的是未完全更新的數據庫,因為可能在讀的時候衹有一部分數據被更新過。使隸屬於同一進程的各綫程協調一致地工作稱為綫程的同步。MFC提供了多種同步對象,下面我們衹介紹最常用的四種: 臨界區(CCriticalSection)
事件(CEvent)
互斥量(CMutex)
信號量(CSemaphore)
通過這些類,可以比較容易地做到綫程同步。 超綫程(HT)是英特爾所研發的一種技術,於2002年發佈。超綫程的英文是HT技術,全名為Hyper-Threading,中文又名超綫程。超綫程技術原先衹應用於Xeon處理器中,當時稱為Super-Threading。之後陸續應用在Pentium 4中,將技術主流化。早期代號為Jackson。
通過此技術,英特爾成為第一間公司實現在一個實體處理器中,提供兩個邏輯綫程。之後的Pentium D縱使不支援超綫程技術,但就集成了兩個實體核心,所以仍會見到兩個邏輯綫程。超綫程的未來發展,是提升處理器的邏輯綫程,英特爾有計劃將8核心的處理器,加以配合超綫程技術,使之成為16個邏輯綫程的産品。
英特爾表示,超綫程技術讓(P4)處理器增加5%的裸晶面積,就可以換來15%~30%的效能提升。但實際上,在某些程式或未對多執行緒編譯的程式而言,超綫程反而會降低效能。除此之外,超綫程技術亦要操作係統的配合,普通支援多處理器技術的係統亦未必能充分發揮該技術。例如Windows 2000,英特爾並不鼓勵使用者在此係統中利用超綫程。原先不支援多核心的Windows XP Home Edition卻支援超綫程技術。 近日據相關消息透露,在HotChips會議上,AMD宣佈下一代代號為Bulldozer“推土機”的處理器架構將采用單核多綫程 技術(multi-threadingtechnology),類似於Intel著名的超綫程技術.
AMD沒有透露有關其多綫程 能力和更多的細節,衹說推土機處理器將在2011年推出,支持單核多綫程 技術.不過,AMD的做法和Intel的 HT是不同的,更類似於Sun的同步多綫程 技術(SimultaneousMulti-Threading),由1個物理核心擴展到4個綫程.“推土機擴展出的單核心多綫程 技術和Intel的超綫程采用的是不同方式.”AMD的代表PatConway也證實了這一點. 有趣的是,早些時候AMD還表示暫不考慮SMT或其他多綫程 技術,並將它應用在當下的處理器中.然而,AMD也認同步多綫程 是未來處理器産品大幅提升性能的必要特徵.
推土機是AMD下一代微架構的處理器,事實上,它將是AMD自2003年後第一次對處理器架構進行重大改變.預計新一代的處理器將提供遠高於目前産品的高性能,同時也加入SSE5指令集.
首款推土機係列桌面處理器代號為Orochi,將會擁有超過4個以上的處理器核心,8M以上的緩存並支持DDR3內存,基於32nm工藝.服務器版處理器代號為Valencia和Interlagos,這兩款處理器將會擁有6、8以及12個處理器核心.
AMD至今從未采用過同步多綫程 (SMT)也就是Intel所稱的超綫程技術。雖然這樣的技術在當年的P4時代顯得並無實際用途,但到了現在,越發普及的多綫程 環境讓超綫程重新煥發了青春。
以目前的應用環境來看,超綫程技術可以讓一些特定應用程序顯著提速達10到15%。除了Intel的在Nehalem、Atom等中引入的超綫程,無論IBM的Power係列,Sun的T1/T2/Rock係列等處理器架構都應用了類似的SMT同步多綫程 技術,用少量的晶體管帶來大幅度的多綫程 性能提升。
一位AMD工程師日前嚮媒體坦誠,不支持單核多綫程 技術讓Opteron處理器看起來性能比不上Intel的低端Xeon。據稱,AMD內部高層已經承認,沒有早早引入此類技術是一項技術選擇上的失誤。
不過,AMD副總裁兼服務器工作站業務總經理Patrick Patla接受采訪時,並沒有明確透露單核多綫程 技術的未來,而是繼續重申已經公佈的Opteron路綫圖:“如果你看一下我們路綫圖以及我們在多綫程 處理器市場的表現就會知道,我們相信每條綫程都擁有完整的核心是目前的最佳選擇。2010年,我們就會推出12核處理器,2011年16核。我們相信未來幾年內我們就能夠完善支持48或64綫程環境,讓我們來看看2012到2013年會帶來些什麽吧。”
既然2011年纔是16核,那麽2012到2013直接跳躍到48甚至64核似乎並不是那麽正常。另外,Patrick Patla前面句句都在講“核”,而到了後面又變成了“綫程”,似乎就在暗示到時AMD可能會采納單核多綫程 技術。 : multithread, multi-thread 進程 下載 單綫程 計算機 軟件 windows api CPU 編程 綫程 Pthread linux多綫程
多綫程序 多綫程技術 C語言多綫程 同步多綫程 多綫程傳輸 多綫程下載 硬件多綫程 多綫程處理 多綫程控製 采用多綫程 多綫程瀏覽器 多綫程支持庫 多綫程服務器 多綫程設計模式 套間模式多綫程 多綫程ping服務器v1.3 cpu多綫程 Win32多綫程 JAVA多綫程設計模式 多綫程 編程技術與實例linux多綫程 linux多綫程設計 多綫程 批量下載機器人Windows多綫程 編程技術與實例 多綫程 批量下載機器人(hdld)v2.9.1.8