程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 基於.NET的多線程編程入門

基於.NET的多線程編程入門

編輯:關於.NET

簡介

多線程在構建大型系統的時候是需要重點關注的一個重要方面, 特別是在效率(系統跑得多快?)和性能(系統工作正常?)之間做一個權衡的 時候。恰當的使用多線程可以極大的提高系統性能。

什麼是線程?

每個正在系統上運行的程序都是一個進程。每個進程包含一到多個線程 。進程也可能是整個程序或者是部分程序的動態執行。線程是一組指令的集合, 或者是程序的特殊段,它可以在程序裡獨立執行。也可以把它理解為代碼運行的 上下文。所以線程基本上是輕量級的進程,它負責在單個程序裡執行多任務。通 常由操作系統負責多個線程的調度和執行。

什麼是多線程?

多線 程是為了使得多個線程並行的工作以完成多項任務,以提高系統的效率。線程是 在同一時間需要完成多項任務的時候被實現的。

使用線程的好處有以下 幾點:

·使用線程可以把占據長時間的程序中的任務放到後台去 處理

·用戶界面可以更加吸引人,這樣比如用戶點擊了一個按鈕 去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度

·程序的運行速度可能加快

·在一些等待的任務實 現上如用戶輸入、文件讀寫和網絡收發數據等,線程就比較游泳了。在這種情況 下我們可以釋放一些珍貴的資源如內存占用等等。

還有其他很多使用多 線程的好處,這裡就不一一說明了。

一些線程模型的背景

我們可 以重點討論一下在Win32環境中常用的一些模型。

·單線程模型

在這種線程模型中,一個進程中只能有一個線程,剩下的進程必須等待 當前的線程執行完。這種模型的缺點在於系統完成一個很小的任務都必須占用很 長的時間。

·塊線程模型(單線程多塊模型STA)

這種模 型裡,一個程序裡可能會包含多個執行的線程。在這裡,每個線程被分為進程裡 一個單獨的塊。每個進程可以含有多個塊,可以共享多個塊中的數據。程序規定 了每個塊中線程的執行時間。所有的請求通過Windows消息隊列進行串行化,這 樣保證了每個時刻只能訪問一個塊,因而只有一個單獨的進程可以在某一個時刻 得到執行。這種模型比單線程模型的好處在於,可以響應同一時刻的多個用戶請 求的任務而不只是單個用戶請求。但它的性能還不是很好,因為它使用了串行化 的線程模型,任務是一個接一個得到執行的。

·多線程塊模型( 自由線程塊模型)

多線程塊模型(MTA)在每個進程裡只有一個塊而不是 多個塊。這單個塊控制著多個線程而不是單個線程。這裡不需要消息隊列,因為 所有的線程都是相同的塊的一個部分,並且可以共享。這樣的程序比單線程模型 和STA的執行速度都要塊,因為降低了系統的負載,因而可以優化來減少系統 idle的時間。這些應用程序一般比較復雜,因為程序員必須提供線程同步以保證 線程不會並發的請求相同的資源,因而導致競爭情況的發生。這裡有必要提供一 個鎖機制。但是這樣也許會導致系統死鎖的發生。

多線程在.NET裡如何 工作?

在本質上和結構來說,.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 {0}", DummyThread.Name);
   Thread DummyPriorityThread = new Thread( new ThreadStart(SomeFunction) );
    DummyPriorityThread.IsBackground=true;
    DummyPriorityThread.Name = "Second Thread";
    DummyPriorityThread.Start( );
   Console.WriteLine ("Started thread {0}", 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 {0}. SomeFunction: {1} ",Thread.CurrentThread.Name, counter);
    }
    }
   catch (ThreadInterruptedException Ex) {
     Console.WriteLine( "Exception in thread {0} ", Thread.CurrentThread.Name);
   }
   finally {
     Console.WriteLine( "Thread {0} Exiting. ",Thread.CurrentThread.Name);
   }
  }
 }
}

·使用Interlock

C#提供了一個特殊的類叫做 interlocked,就是提供了鎖機制的實現,我們可以加入如下的代碼實現鎖機制 :

Interlocked.SomeFunction (ref counter);

·使用鎖

這是為了鎖定代碼關鍵區域以 進行同步,鎖定代碼如下:

lock (this){ Some statements ;}

·使用Monitor

當有需要進行線程管理的時候我們 可以使用:

Monitor.Enter(this);

其他也有一些 方法進行管理,這裡就不一一提及了。

線程的缺點

線程自然也有 缺點,以下列出了一些:

·如果有大量的線程,會影響性能,因 為操作系統需要在他們之間切換;

·更多的線程需要更多的內存 空間

·線程會給程序帶來更多的bug,因此要小心使用

·線程的中止需要考慮其對程序運行的影響

·通常 塊模型數據是在多個線程間共享的,需要一個合適的鎖系統替換掉數據共享

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