Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Управление циклом при распараллеливании






Напомню, метод Parallel.For имеет множество реализаций и по синтаксису является функцией, возвращающей значение типа ParallelLoopResult. До сих пор метод вызывался как оператор, и возвращаемое значение никак не использовалось. Попробуем разобраться, как и в каких ситуациях следует использовать значение, возвращаемое методом.

Рассмотрим обычный оператор цикла for. Возможны следующие ситуации при его выполнении:

· Нормальное завершение. Все итерации цикла завершились без каких-либо происшествий.

· Преждевременное завершение итерации. В ходе итерации выполнен оператор continue, что ведет к прерыванию текущей итерации и переходу на следующую итерацию.

· Преждевременное завершение цикла. В ходе итерации выполнен оператор break, что ведет к прерыванию текущей итерации и выходу из цикла.

· Аварийное завершение итерации. В ходе итерации возникла исключительная ситуация, что ведет к прерыванию цикла и необходимости обработки возникшей ситуации.

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

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

Если одна или несколько итераций завершаются преждевременно, то и здесь кроме завершения текущей итерации ничего предпринимать не нужно, поскольку другие итерации запускаются автоматически.

Если на итерации с номером i выполнился метод break, то цикл необходимо завершить. Для параллельного выполнения это означает завершение всех уже запущенных итераций, запуск на выполнение всех еще не запущенных итераций с номерами, меньшими i. Запуск итераций с номерами, большими i, отменяется, если они конечно еще не были запущены. Заметьте, поскольку одновременно выполняются несколько итераций, то break может выполняться не один раз. Если например break выполнился на итерациях с номерами 10 и 20, то запускать нужно итерации, номера которых меньше 10.

Если на итерации с номером i возникла исключительная ситуация, то цикл необходимо завершить, а ситуацию обработать. Поскольку одновременно выполняются несколько итераций, то исключительные ситуации могут возникать на разных итерациях. Поэтому выбрасывается агрегирующая исключительная ситуация Aggregation Exception, которая содержит информацию обо всех возникших исключительных ситуациях. Следует предусмотреть catch блок, обрабатывающий эту ситуацию.

Как же выполнить оператор break при параллельном исполнении? Для этого нужно использовать перегруженную версию Parallel.For, в которой методу, выполняющему итерацию, помимо индекса цикла передается дополнительный параметр класса ParallelLoopState. Объект этого класса может вызывать метод Break, который и реализует стратегию прерывания для параллельного выполнения. Анализируя возвращаемое значение метода Parallel.For, можно узнать минимальный номер итерации, на которой впервые выполнялось прерывание (break). Помимо метода Break объект класса ParallelLoopState может вызывать и метод Stop, который также завершает все выполняемые итерации, но, в отличие от Break, не вызывает на исполнение итерации с меньшими номерами. Вызов Stop означает остановить выполнение. В этом случае теряет смысл понятие итерации с минимальным номером, прервавшей выполнение.

Значение, возвращаемое методом Parallel.For, представляет структуру ParallelLoopResult, у которой два поля. Булевское поле IsCompleted возвращает значение true, если все итерации закончились без происшествий, и false, в противном случае. Если на одной или нескольких итерациях выполнялся break, то поле LowestBreakIteration вернет значение минимальной итерации.

static void Grad(int i, ParallelLoopState pls)

{

int N = i;

const int m = 150;

int k =0;

while (N! = 1)

{

if (N % 2 == 0)

N = N / 2;

else

N = 3 * N + 1;

k++;

// if (k == m) pls.Stop();

if (k == m) pls.Break();

}

}

 

static void Break_Stop_Test()

{

ParallelLoopResult res;

res = Parallel.For(2, n, Grad);

Console.WriteLine(res.LowestBreakIteration.ToString());

Console.WriteLine(res.IsCompleted.ToString());

}

 

У объектов класса ParallelLoopState есть ряд полезных свойств, позволяющих разным итерациям цикла обмениваться информацией о возникающих событиях.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.