Главная · Карта сайта · Поиск · Статьи · Компьютерные курсы · Обучающие программы · Открытые проекты · Веб-программирование · Создание интернет-сайта · Полезные ссылки · Глоссарий · Контакты · Декабрь 09 2016 20:19:55
Последнее опубликованное

Что такое Model-View-Controller
Pattern Model-View-Controller

Как создать свой веб-сайт
Как создать свой сайт в интернете

Разное
Статистика

Программирование на C#. Параллельные вычисления. Цикл For


[Назад] [Следующая страница]

6.3. Конструкция Parallel.For

Конструкции Parallel стали доступны с появлением .NET 4.0. С их использованием достаточно легко реализовать параллельные вычисления, если не требуется отдельно контролировать ход выполнения каждого отдельного потока. Далее представлен фрагмент кода из демонстрационной программы, работу которого вы можете наблюдать, запустив эту самую демонстрационную программу и нажав кнопку [Старт] на первой закладке. Код реализует выполнение цикла, аналогичного циклу for, но с той лишь разницей, что каждая итерация выполняется в отдельном потоке. Пример построен таким образом, что некоторые итерации могут так и не “засветиться” в отчете о работе, поскольку за них всю работу выполнили другие итерации.

Теперь более подробно. Задано определенное количество параллельных потоков, для каждого из которых конструкцией Parallel.For создается отдельный поток или нить исполнения - Thread. Каждый такой поток выполняет действия, описанные методом _DoWork() до тех пор, пока общий счетчик _SharedCount не достигнет своего максимума. Максимальное значение _SharedCount определяется, как квадрат от заданного количества потоков. Система распределяет процессорное время по своему усмотрению, по известным только ей правилам и законам, и может случиться так, что некоторые итерации так и не успеют ни разу выполнить тело цикла while() {}. У каждого потока имеется свой собственный счетчик выполнения _DoWork(). Пример работы демонстрационной программы представлен ниже. Видно, что 4 из 10 потоков так ни разу и не “приложились к общему делу”, а некоторые из потоков успели это сделать аж 26 раз.

Пример работы обучающей программы
Пример работы программы с конструкцией Parallel.For.

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

        //Пример 1. Parallel.For
        private void btnStartParallelFor_Click(object sender, EventArgs e)
        {
            textBoxParallelFor.Text = string.Empty;

            //Количество потоков
            int _ThreadsCount = Convert.ToInt32(numericUpDownThreadsCount.Value);
            //Массив счетчиков для создаваемых потоков
            int[] _Counts = new int[_ThreadsCount];
            //Общий счетчик - разделяемый ресурс
            int _SharedCount = 0;

            //Журнал сообщений
            string _Log = string.Empty;
            //Объект - блокировка для разграничения доступа к журналу
            object _LogLock = new object();

            //Количество итераций
            int _SharedCountMax = _ThreadsCount * _ThreadsCount;

            //Универсальный делегат - тело цикла с параллельной обработкой итераций
            Action<int> _ForAction = (i) =>
                {
                    while (_SharedCount < _SharedCountMax)
                    {
                        //Имитация 'бурной деятельности'
                        _DoWork();
                        //Каждый поток имеет свой счетчик, поэтому разграничение доступа не требуется
                        _Counts[i]++;
                        //Потокобезопасная операция инкремента (_SharedCount++)
                        //Операции Interlocked являются атомарными и не требуют блокировок типа lock() {}
                        //Это позволяет избежать потерь в производительности, связанных с блокировками
                        Interlocked.Increment(ref _SharedCount);

                        //Потокобезопасная модификация _Log с использованием блокировки 
                        lock (_LogLock)
                        {
                            _Log = _Log + "Общий счетчик: " + _SharedCount.ToString() 
                                + "; Счетчки[" + i.ToString() 
                                + "]: " + _Counts[i].ToString() + Environment.NewLine;
                        }
                    }  
                };

            //Цикл с параллельной обработкой итераций: for (int i = 0; i < _ThreadsCount; i++) _ForAction(i)
            Parallel.For(0, _ThreadsCount, _ForAction);

            //Формирование и вывод отчета
            _Log = _Log + Environment.NewLine +"Итог:" + Environment.NewLine;

            for (int i = 0; i < _ThreadsCount; i++)
                _Log = _Log + "Счетчик[" + i.ToString() + "]: " + _Counts[i].ToString() + Environment.NewLine;

            textBoxParallelFor.Text = _Log;
        }
        //Имитация обработки данных
        internal void _DoWork()
        {
            int _Iterations = Convert.ToInt32(numericUpDownWork.Value);

            for (int i = 0; i < _Iterations; i++)
                for (int j = 0; j < 100000; j++) { }
        }

Использованные в примере универсальный делегат и лямбда-выражения рассматривались в курсе программирования C# Quick Guide™ ранее здесь.



[Назад] [Следующая страница]

Компьютерные курсы и курсы программирования
Основы программирования

Курс для начинающих программистов на C# и VB.NET.

SQL 25™

Построение SQL запросов и работа с базой данных.

C# Quick Guide™

Программирование на C#. Краткое руководство.

RegEx

Применение регулярных выражений.

Plug-in архитектура

Примеры программной Plug-in архитектуры.

XML и его расширения

Язык разметки XML и его расширения с примерами.

HTML и разметка гипертекста

Языки HTML, XHTML и CSS с примерами разметки.

Основы веб-дизайна

Основы веб-дизайна: решения типовых задач верстки.

Программирование на PHP

Руководство по программированию на PHP для начинающих.

Справочные материалы

Шаблоны проектирования
Каталог шаблонов проектирования программных компонентов.

Рефакторинг кода
Каталог приемов рефакторинга программного кода.

Гость
Имя

Пароль



Забыли пароль?
Запросите новый здесь
.
Coding Craft. Все права защищены © 2011. Проект Инициативного Народного Фронта Образования - ИНФО-проект.