Многопоточное программирование на языке MC#
Цель - изучить назначение и применение async-методов языка MC# и сравнить их с традиционными средствами многопоточного программирования .NET
Для создания многопоточных приложений, предназначенных для исполнения на многоядерных (многопроцессорных) машинах, в языке MC# используются асинхронные методы. Они являются единственным средством создания параллельных процессов (потоков) в этом языке (если не считать movable-методов, которые являются "распределенными" аналогами локальных асинхронных методов).
Общий синтаксис определения асинхронных методов в языке MC# следующий:
Задание ключевого слова async при определении некоторого метода означает, что при вызове данного метода он будет запущен в идее отдельного потока локально, т.е., на машине, где произошел его вызов (возможно, на отдельном ядре/процессоре). В систему исполнения (Runtime-систему) языка MC# встроена подсистема автоматической балансировки нагрузки, которая на основе оценки загруженности процессоров машины, привязывает порождаемый поток (асинхронный метод) к наименее загруженному процессору.
Отличия асинхронных методов от обычных состоят в том, что
- вызов async-методов заканчивается, по существу, мгновенно (время тратится только на запуск нового потока),
- async-методы никогда не возвращают результатов (для взаимодействия async-методов между собой и другими частями программы в языке MC# предусмотрены специальные средства - каналы и обработчики канальных сообщений).
Задача 1. Написать на языке MC# параллельную программу перемножения двух матриц с использованием async-методов.
Каждый async-метод должен вычислять свою часть - стрoки - результирующей матрицы, где количество этих строк определяется числом N / P, где N - количество строк в результирующей матрице, P - количество асинхронных методов.
Для обнаружения момента окончания async-методов необходимо завести специальный объект с внутренним счетчиком (некоторой целочисленной переменной). Этот счетчик (при предварительном блокировании объекта, которому он принадлежит) наращивается каждым async-методом при завершении его работы, а главная программа с заданным интервалом проверяет значение этого счетчика.
Если задание выполняется на многоядерной (многопроцессорной) машине, сравнить время исполнения последовательного варианта программы с параллельным, где в последнем число асинхронных методов равно числу доступных ядер/процессоров.
Задача 2. Разработать параллельную программу перемножения двух матриц с использованием стандартных средств многопоточного программирования в .NET, а именно с использованием класса Thread. Для обнаружения момента завершения работы потоков, воспользоваться либо методом из Задачи 1 данного задания, либо командой Join класса Thread.
Сравнить время выполнения данной программы с эквивалентным вариантом из Задачи 1, написанным на языке MC#.