Умножение матриц с использоанием многопоточного программирования - C#
Формулировка задачи:
Нужно переделать однопоточное в многопоточное
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int[,] m1 = new int[10, 10]; //объяление матрицы 1
int[,] m2 = new int[10, 10];//объяление матрицы 2
int[,] m3 = new int[10, 10]; //объяление произведения матрицы
Random ran = new Random(); // Заполнение случайными числами
for (int m = 0; m < 10; m++)
{
for (int je = 0; je < 10; je++)
{
m1[m, je] = ran.Next(30); // ran.Next(функция задает максимально допустимое значение);
m2[m, je] = ran.Next(30);
}
}
for (int m = 0; m < 10; m++)
{
for (int je = 0; je < 10; je++)
{
m3[m, je] = m1[m, je] * m2[m, je]; // Произведение матриц
}
}
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Матриц m1 и m2:");
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
Console.Write(m1[i, j].ToString("000") + " "); // вывод в консоль м1
}
Console.WriteLine();
}
}
Console.WriteLine("Матриц m2:");
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
Console.Write(m2[i, j].ToString("000") + " "); // вывод в консоль м2
}
Console.WriteLine();
}
Console.WriteLine("Произведение двумерных матриц m1 и m2:");
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
Console.Write(m3[i, j].ToString("000") + " "); // вывод в консоль *
}
Console.WriteLine();
}
Console.ReadKey();
}
}
}Решение задачи: «Умножение матриц с использоанием многопоточного программирования»
textual
Листинг программы
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ThreadKR
{
class MainClass
{
//Объект для блокировки
private static object LockThis = new System.Object ();
//Количество потоков
public const int ThreadCount = 10;
//Сумма (разделяемое между потоками поле)
public static double Sum = 0;
//Произведение (разделяемое между потоками поле)
public static double Prod = 1;
//Левая граница
public const double LeftBound = 1;
//Правая граница
public const double RightBound = 20;
//Приращение
public const double DeltaX = 0.2;
//Параметр a
public const double a = 1;
//Параметр b
public const double b = 2;
//Параметр c
public const double c = 3;
//Общее количество итераций
public static int IterationCount;
//Максимальное количество итераций на 1 поток
public static double ThreadIterationCount;
// Функция потока f(x)=a*x^2 + b*x + c
static void Function(object Params)
{
//Получение параметров
//Левая граница куска
double LocalLeftBound = Convert.ToDouble ((Params as object[]) [0]);
//Правая граница куска
double LocalRightBound = Convert.ToDouble ((Params as object[]) [1]);
//Приращение
double LocalDeltaX = Convert.ToDouble ((Params as object[]) [2]);
//Имитация задержки
Thread.Sleep (Convert.ToInt32 (Math.Round ((new Random ()).NextDouble () * 1000)));
for (double i = LocalLeftBound; i<LocalRightBound; i+=LocalDeltaX) {
//Блок доступа к разделяемому ресурсу
lock (LockThis) {
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// Вычисление f(i)=a*i^2 + b*i + c суммы и произведения
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Sum = Sum + (a * i * i + b * i + c);
Prod = Prod * (a * i * i + b * i + c);
}
}
Console.WriteLine ("Вызов потока {0}",Convert.ToString((Params as object[])[3]));
}
public static void Main (string[] args)
{
Stopwatch sw = new Stopwatch ();
Console.WriteLine ("Исходные данные\n" +
"Функция f(x)=a*x^2 + b*x + c");
Console.WriteLine (
"Левая граница перебора: {0}\n" +
"Правая граница перебора: {1}\n" +
"Приращение: {2}\n"+
"Количество потоков: {3}",
LeftBound,RightBound,DeltaX,ThreadCount);
IterationCount = Convert.ToInt32((RightBound - LeftBound) / DeltaX);
ThreadIterationCount = Convert.ToInt32(IterationCount / ThreadCount);
Console.WriteLine (
"Общее количество итераций: {0}\n" +
"Максимальное количество итераций на 1 поток: {1}",
IterationCount,ThreadIterationCount
);
sw.Start ();
// Создаем ссылки на потоки
Thread[] thr=new Thread[ThreadCount];
double p1, p2;
// Создаем и запускаем потоки
for (int i=0; i<ThreadCount; i++)
{
p1 = LeftBound + i * ThreadIterationCount * DeltaX;
p2 = LeftBound + (i+1) * ThreadIterationCount * DeltaX;
Console.WriteLine (
"Локальная левая граница: {0}\n"+
"Локальная правая граница: {1}\n"+
"Приращение: {2}\n",
p1,p2,DeltaX
);
thr [i] = new Thread (Function);
thr [i].Start (new object[] {p1,p2,DeltaX,thr[i].ManagedThreadId});
}
for (int i=0; i<ThreadCount; i++)
thr [i].Join ();
sw.Stop ();
Console.WriteLine (
"Результаты расчетов:\n"+
"Сумма: {0}\n" +
"Произведение: {1}\n"+
"Затраченное время (милисек): {2}",
Sum,Prod,sw.ElapsedMilliseconds
);
}
}
}