Несколько потоков, обновляющих массив

Я пытаюсь реализовать многопоточность в моем приложении, которая делает много вычислений числа с плавающей запятой (нейронная сеть).

Я написал функцию, которая делает необходимые вычисления и обновляет массив вне этой функции. Мой фактический однопоточный код выглядит так (упрощен для лучшего понимания):

class MyClass
{
 // this array after all calculations should contain 
 // result of only one calculation, 
 // that returned smallest value in one of array fields 
 // (smallest neural network error)
 float[] bestResult;
 // runs calculations on all "sets of data"
 public void findBestResult(void)
 {
 foreach (something...) // data rows from database cached in one array
 {
 calculate(x[]);
 }
 }
 // calculates one "set of data"
 public void calculateAndUpdateResultIfBetter(float[] inputData)
 {
 if (bestResult[0] > calculatedData[0])
 bestResult = calculatedData; // update only if condition is true
 }
}

Я программист на низком уровне, я не знаю, как использовать передовые (?) методы потоковой передачи .NET, которые используют Synchronize и т.д. Я знаю, как создать один дополнительный поток для чего-то и обновить некоторые элементы управления по форме с помощью делегатов.

Я не знаю, как работать с 2-8 потоками, делающими то же самое и конкурируя друг с другом.

Вопрос 1 - вы можете мне помочь? Я не знаю, с чего начать. Решено Нико Драшковичем

EDIT: Вопрос 2 - метод lock() блокирует мой массив для чтения и записи?

1 ответ

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

float[] bestResult;
object sync = new Object();

Затем вокруг кода, который обращается к массиву, вы используете lock:

lock (sync) {
 if (bestResult[0] > calculatedData[0]) {
 bestResult = calculatedData;
 }
}

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

licensed under cc by-sa 3.0 with attribution.