2014-01-30 2 views
1

Я пытаюсь использовать threading для получения списка простых чисел. Однако, когда я запускаю программу, я получаю избыточные простые числа в результате.Получение неожиданного многопоточного поведения

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) не берет начало-конец пары. Требуется start и count.

Вы бы нашли эту ошибку самостоятельно, используя отладчик и проверив состояние выполнения. Просто смотреть на багги код часто не приводит к его обнаружению. Требуется расследование.

Кроме того ваш код потокобезопасно хотя гораздо более сложным, чем это было бы использовать что-то вроде PLINQ:

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

работы на более высоком уровне. Не управлять потоками.

+0

Спасибо, друг. Я только что скопировал и использовал первый раз: D –

+0

Не имеет значения, откуда пришел код. Это важный навык, позволяющий исправить любой фрагмент кода, исследуя его. Вам часто приходится исправлять вещи других народов. Рад, что ваша проблема решена. – usr

Смежные вопросы