Параллельное выполнение, вызывающее потокобезопасность метода

#c# #parallel-processing #parallel.foreach

#c# #параллельная обработка #parallel.foreach

Вопрос:

Имея следующее:

 List<Person> persons = // list of persons
Parallel.ForEach(persons, (i) => {
      AddAge(i);
});

// Does this method needs to be thread safe?
// Why?
public void AddAge(Person person)
{
    // Multiple threads execute here at once. However they're  
    // working with their own "person" object, therefore    
    // each thread won't corrupt others "person" object - is this assumption correct?
    person.Age =  10;
}
  
  • Поскольку каждый пользователь обновляется «отдельно» в своих отдельных потоках, и один из них не имеет ничего общего с другим, должен ли метод AddAge() быть потокобезопасным?
  • Выполняет ли CLR свою собственную копию «AddAge ()» для каждого потока, разделяя ее между потоками?

Комментарии:

1. Passed by reference вы ничего не передаете по ссылке в этой строке. Кроме того, вы AddAge вычисляете число, а затем отбрасываете его на пол; на самом деле он ничего не делает с созданным им числом (которое не будет компилироваться).

2. Person — это ссылочный тип. Поэтому, когда он попадает в AddAge, он отправляет ссылку на этот объект. не так ли?

3. Значение переменной является ссылкой. Однако эта переменная передается по значению, а не по ссылке.

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

5. @BobSwanson Нет, код не компилируется.

Ответ №1:

Потокобезопасность связана с изменением одних и тех же данных из нескольких потоков. Если вы работаете с отдельными данными (например, вашими Parallel.ForEach ) и правильно стробируете свою работу, чтобы пакеты выполнялись до выполнения зависимой работы, вам не нужен потокобезопасный код внутри, поскольку вы выполняете потокобезопасность вне метода (гарантируя, что каждый поток получает свой собственный набор данных для работы).

Комментарии:

1. @Guvante-«(гарантируя, что каждый поток получает свой собственный набор данных для работы)». — это означает, что у каждого потока будет своя собственная копия AddAge?

2. @BobSwanson что вы называете «собственной копией AddAge»? Сами методы не имеют экземпляров — обычно для каждого метода выполняется одна копия кода на домен приложения… Возможно, вы имеете в виду локальные переменные (которые не показаны в вашем примере) — на самом деле локальные переменные относятся к вызову метода…

3. идеально: «локальные переменные для каждого вызова метода». Спасибо