2011-03-31 31 views
0

我一直在閱讀並行編程,甚至現在仍然對整個概念有點困惑。比方說,我有一個約5個類互相交互的單個項目,並且方法和變量中的局部變量可以被單個類中的所有方法訪問,甚至可以通過實例化訪問所有類的1或2個變量。 現在使用線程我知道全局變量將被多個線程覆蓋,如果沒有鎖定應用,但方法/函數沒有本地變量,對不對? 因此,如果我作爲一個新進程多次運行項目,那麼這些方法和變量將是線程安全的,並且不會發生數據損壞? 因此,爲了使用任務工廠來實現並行編程,如果我創建了一個基本上創建任務的項目,並且每個任務基本上都在運行另一個項目的實例,那麼變量和數據是否應該不是線程安全和安全的? 但是如果我有輸出文件,並且他們按輸出& datetime.now.tostring命名,會不會有衝突問題,並且我知道我在試用它時已經看到了這種情況。在.net 4.0中並行編程

dim factory as new taskfactory 
factory.startnew(addressof projectinstance.main) 

現在這對大多數人來說可能是常識,所以請在這裏溫柔批評。非常感謝任何迴應。

編輯:

這是在其中一個類文件的創建模塊:

Private Sub createXML() 
    num += 1 
    Dim fileList As New ArrayList 
    Dim counter As Integer = 0 
    Dim file As String = Module1.infile 
    xmlfile = directoryPath & "\Feed" & DateTime.Now.ToUniversalTime.ToString("yyyyMMddhhmmss") & endExtension 
    fileList.Add(xmlfile) 
    Thread.Sleep(2000) 
    Dim doc As XmlDocument = New XmlDocument 
    xwriter = New XmlTextWriter(xmlfile, Encoding.UTF8) 
    xwriter.Formatting = Formatting.Indented 
    xwriter.Indentation = 2 
    xwriter.WriteStartDocument(True) 
    xwriter.WriteStartElement("Posts") 
    Dim j As Integer = 0 
    For i As Integer = 0 To gXmlList.Count() - 1 
     j += 1 
     parseXML(gXmlList(i)) 

....

回答

1

這是單程序多數據SPMD pattern。你基本上爲每個任務創建一個單獨的程序或對象圖(任務在一個線程上被排定)。對象圖的全局變量實例將會很好(所以沒有靜態全局變量),但仍然需要擔心像文件這樣的共享資源。

解決這些類型問題的一種方法是爲每個任務實例分配一個唯一的ID或「級別」,並使用它來標識資源並對其進行命名。在您的文件示例中,每個任務都會輸出一個名爲myoutput_ {rank} .txt的文件。如果你真正想要的是一個文件,那麼你的應用程序必須實現一個後期處理,聚合階段,它將合併結果。這種情況在並行性結束後順序發生。這就像一張地圖/減少。每個並行任務運行相同的「程序」以將一些輸入數據映射到輸出數據集(您的案例中的文件),然後在單獨的步驟中將結果減少或彙總爲最終答案。

下面是一個例子:

static void Main() 
    { 
     const int maxJobs = 10; 

     // Run jobs and wait... 
     List<Task> tasks = new List<Task>(); 
     for (int rank = 0; rank < maxJobs; rank++) 
      tasks.Add(Task.Factory.StartNew((r) => { new MyApp().Main((int)r); }, rank)); 

     Task.WaitAll(tasks.ToArray()); 

     // Aggregate results... 
     StringBuilder sb = new StringBuilder(); 
     for (int rank = 0; rank < maxJobs; rank++) 
      sb.AppendLine(File.ReadAllText("results_" + rank + ".txt")); 

     Console.WriteLine(sb.ToString()); 
     File.WriteAllText("results_final.txt", sb.ToString()); 
     Console.ReadLine(); 
    } 

    public class MyApp 
    { 
     public void Main(int rank) 
     { 
      Console.WriteLine("Starting {0}", rank); 
      File.WriteAllText("results_" + rank + ".txt", "result data " + rank); 
     } 
    } 

,因爲它喜歡的類MyApp的能有儘可能多的狀態。它甚至可以與子對象共享該狀態,但它不能具有靜態或共享狀態,而全局變量是在MyApp外部讀/寫定義的全局變量。

可以只讀全局狀態。例如,所有MyApp實例都可以從單個文件讀取輸入數據。不幸的是,MyApp的多個實例讀取而不實現某種形式的協調(如鎖),將其寫入(單個)全局變量,對象實例或其他資源(如文件)。

在上面的示例中,每個任務創建一個本地results_ {rank} .txt文件。這些內容在單獨的聚合步驟中合併爲一個結果文件results_final.txt。無法並行執行此操作,因爲所有任務都將寫入單個全局資源。

很多這些概念都包含在本書和示例中,您可以在這裏找到。該內容也可以在MSDN上免費使用。

http://parallelpatterns.codeplex.com/

+0

感謝您的回覆,真的很感激....在MyApp的定義全局變量將包括我的輸出文件我生成這樣在技術上那麼這將是確定......因爲每個任務需要一個輸入文件和使用該輸入文件創建相應的輸出文件。這是正確的嗎? – vbNewbie 2011-03-31 19:14:36

+0

我更新了我的答案。 results_ {rank} .txt文件不是全局的,它們對每個任務都是本地的。如果你想要一個單一的results.txt文件,那麼這將被視爲全局狀態。請注意,全局只讀狀態爲OK。全局寫入或讀取/寫入不是。 – 2011-03-31 19:53:59