Parallel.For: безопасно ли блокировать значение? - PullRequest
0 голосов
/ 18 мая 2011

Я пытаюсь выяснить вывод этого кода:

Dictionary<int, MyRequest> request = new Dictionary<int, MyRequest>();

for (int i = 0; i < 1000; i++ )
{
  request.Add(i, new MyRequest() { Name = i.ToString() });
}

var ids = request.Keys.ToList();

Parallel.For(0, ids.Count, (t) =>
{
  var id = ids[t];
  var b = request[id];

  lock (b)
  {
    if (b.Name == 4.ToString())
    {
      Thread.Sleep(10000);
    }

    Console.WriteLine(b.Name);
  }
});

Console.WriteLine("done");
Console.Read();

output:

789
800
875
.
.
.
4
5
6
7
done

MyRequest - просто фиктивный класс, используемый для демонстрации (ничего не делает, но держит ценности).Моя блокировка блокирует выполнение или последние 4 помещаются в собственный поток?

Это демонстрационная версия .NET 4.0.

ОБНОВЛЕНИЕ Хорошо, я понялони были в том же потоке, но я все еще хотел бы знать, если блокировка делает что-нибудь, чтобы заблокировать выполнение.Я не могу себе представить, что это так.

Ответы [ 3 ]

2 голосов
/ 18 мая 2011

Если ids не содержит дубликатов, эта блокировка ничего не заблокирует. Но если в ids есть дубликаты, то да, может возникнуть конфликт при блокировке, поскольку разные потоки борются за доступ к одному и тому же запросу.

2 голосов
/ 18 мая 2011

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

1 голос
/ 18 мая 2011

Parallel.For использует пул потоков для обработки вашего цикла. Как только один из его потоков освобождается, он назначает его следующему элементу. Это недетерминировано, потому что вы не знаете, сколько потоков в пуле, и вы не контролируете время процессора, выделяемое каждому потоку. Это означает, что некоторые потоки могут закончиться раньше или позже, чем вы, естественно, ожидаете.

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

...