2014-01-30 45 views
1

我正嘗試使用線程來獲取素數列表。但是,當我運行該程序時,我在結果中得到冗餘素數。獲取意想不到的多線程行爲

static void Main(string[] args) 
     { 
      try 
      { 
       var r2 = DoThread(); 
       Array.Sort(r2); 
      } 
      catch (Exception e) 
      { } 
     } 

public static int[] DoThread() 
     { 
      var task = new List<MyThread>(){ 
       new MyThread(){start = 3, end = 25000}, 
       new MyThread(){start = 25001, end = 50000}, 
       new MyThread(){start = 50001, end = 75000}, 
       new MyThread(){start = 75001, end = 100000-3} 
      }; 
      var threads = new List<Thread>() 
      { 
       new Thread(task[0].MyDelegate), 
       new Thread(task[1].MyDelegate), 
       new Thread(task[2].MyDelegate), 
       new Thread(task[3].MyDelegate) 
      }; 

      threads.ForEach(t => { t.Start(); }); 
      threads.ForEach(t => { t.Join(); }); 

      var res = new List<int>(); 
      task.ForEach(t => res.AddRange(t.result)); 
      return res.ToArray(); 
     } 

public class MyThread 
    { 
     public int[] result; 
     public int start; 
     public int end; 

     public void MyDelegate() 
     { 
      IEnumerable<int> numbers = Enumerable.Range(start, end); 
      var parallelQuery = 
       from n in numbers 
       where Enumerable.Range(2, (int)Math.Sqrt(n)).All(i => n % i > 0) 
       select n; 
      result = parallelQuery.ToArray(); 
     } 
    } 
+0

「冗餘素數」是什麼意思? –

+0

你是指DUPLICATE素數? – Polyfun

+0

我得到相同的素數,比如說11,在合併所有四個後的最終結果數組中得到兩次。,,, 11,11,13,17,19,19,23 ... –

回答

1

Enumerable.Range(start, end)不採用起始端對。它需要startcount

通過使用調試器並檢查運行時狀態,您本可以自己發現此錯誤。只看代碼錯誤通常不會導致發現它。需要調查。

除此之外,你的代碼是線程安全的,雖然遠遠複雜得多,它會使用類似PLINQ了:上了一個臺階

var res = tasks.AsParallel().SelectMany(t => t.GetPrimes()).ToList(); 

工作。不要管理線程。

+0

感謝哥們。我剛剛複製並使用了第一次:D –

+0

代碼來自哪裏並不重要。通過調查能夠修復任何代碼是一項重要技能。你經常需要修復其他人的東西。很高興你的問題解決了,但。 – usr