2015-08-17 2 views
3

MSDNParallel.For «Thread локальное состояние»

Мой вопрос заключается в следующем: третий параметр в Parallel.For, что он делает?

Когда я меняю его на() => 1d, он удваивает мой результат, устанавливается на две его тройки, но игнорирует десятичные знаки.

Почему он игнорирует десятичные знаки, если это был какой-то удвоение? Что на самом деле происходит там?

Теперь я попытался добавить блокировки. И он не просто инициализирует промежуточный результат указанному значению.

Вот код Im используя:

static void RunParallelForCorrectedAdam() 
{ 
    object _lock = new object(); 
    double result = 0d; 
    // Here we call same method several times. 
    // for (int i = 0; i < 32; i++) 

    Parallel.For(0, 32, 
     //  Func<TLocal> localInit, 
    () => 3d, 
     //  Func<int, ParallelLoopState, TLocal, TLocal> body, 
     (i, state, interimResult) => 
     { 
      lock (_lock) 
      { 
       return interimResult + 1; 
      } 

     }, 
     //Final step after the calculations 
     //we add the result to the final result 
     // Action<TLocal> localFinally 

     (lastInterimResult) => 
     { 
      lock (_lock) 
      { 
       result += lastInterimResult; 
      } 
     } 
    ); 
    // Print the result 
    Console.WriteLine("The result is {0}", result); 
} 
+4

Из ссылки, которую вы указали, объясняется именно то, что делает 0d. – BugFinder

+1

Но это так. Если вы инициализируете переменную для возврата с 3, она даст вам результат 3+ вашего результата. – BugFinder

+0

Я думал, вы не хотите мне помогать. Я извиняюсь. Ive обновил код сейчас. Если я изменю его на 1, это даст мне 34-36. если я изменю его на 2, это даст мне 34-40. Если я изменю его на 3, это даст мне около 34-50. Что это? И если я просто оставлю это на 0d, это даст мне 32 в результате. – MakerOfTheUnicake

ответ

2

С () => 3d, result будет 32 + 3 * t, где t - это количество потоков, которые были использованы. 3d передается как interimResult на первый звонок body в каждом потоке.

Целью Parallel.For является распространение работ по нескольким потокам. Таким образом, interimResult + 1 выполняется ровно 32 раза (возможно, на разных потоках). Но каждый поток должен иметь некоторое начальное значение для interimResult. Это значение, которое возвращается localInit.

Так что если работа распространяется, например, два threds, каждый из которых делает + 1 16 раз и таким образом вычисляет 3 + 16. В конце частичные результаты суммируются, получая 6 + 32.

Короче говоря, в этом примере не имеет смысла для localInit возвращать somthing отличное от 0d.

+0

Да, это правда. Я подтвердил это сейчас. Это самое близкое объяснение того, что я вижу. Почему это будет умножение потоков? Где происходит это размножение нитей? – MakerOfTheUnicake

+0

Отлично. Вы, сэр, мой первый рыцарь в коде. – MakerOfTheUnicake

0

Мой вопрос: Третий параметр в Parallel.For, что он делает?

Это Func, который запускается один раз в потоке. Если для вашей петли требуется локальная переменная потока, это где вы ее инициализируете.

EDIT:

Шаг за шагом:

(i, state, interimResult) => interimResult + 1, 

Вы понимаете, что interimResult ваша локальная переменная, то же один вы инициализируется как 0D?

+0

Это не объясняет его поведение. – MakerOfTheUnicake

+0

@MakerOfTheUnicake см. Мое редактирование –

+0

Спасибо за ваш ответ! Нет, я не понимаю, что это так. Я не могу заставить себя вести себя так. – MakerOfTheUnicake