Anonim_999

Nikita

Nov 22nd, 2022 (edited)
807
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.76 KB | None | 0 0
  1. using System;
  2. using System.Threading;
  3.  
  4. namespace ConsoleApplication1
  5. {
  6.     class Program
  7.     {
  8.         public static int[] A; //Числовой массив А
  9.         public static int[] C; //Числовой массив C
  10.         public static int CountElements; //поле, которое хранит в себе какое количество элементов будет в массивах
  11.         public static int CountThreads; //поле, которое хранит в себе количество потоков
  12.         public static int Result = 0; //поле где будет хранится итоговый результат
  13.         public static object Locker = new object(); //Объект чтобы передать в Lock, ниже написано что такое Lock
  14.  
  15.         static void Main(string[] args)
  16.         {
  17.             string input; //переменная для хранения пользовательского ввода
  18.             int subArrayLen = 0; //длина части массива, ниже пояснение будет для чего она
  19.             Console.Write("Arrays count elements: ");
  20.             input = Console.ReadLine(); //Сбор пользовательского ввода
  21.  
  22.             /*int.TryParse() пытается конвертировать переменную в число, возвращает true false
  23.              * true - если получилось конвертировать
  24.              * false - если нет
  25.              *
  26.              * ниже условие, пробует конвертировать пользовательский ввод в переменную CountElements
  27.              * а так же проверяет, чтобы количество не было меньше 1
  28.              * если что-то пошло не так, пользователю выдаст ошибку, CountElements станет стандартным значением: 10
  29.              */
  30.             if (!int.TryParse(input,out CountElements) || CountElements < 1)
  31.             {
  32.                 CountElements = 10;
  33.                 Console.ForegroundColor = ConsoleColor.Red;
  34.                 Console.WriteLine($"Input error. count elements - {CountElements}");
  35.                 Console.ResetColor();
  36.             }
  37.             A = new int[CountElements]; //Инициализируется массив А, где его размер задается CountElements
  38.             C = new int[CountElements]; //Инициализируется массив C, где его размер задается CountThreads
  39.             Console.Write("Threads count: ");
  40.             input = Console.ReadLine(); //Сбор пользовательского ввода
  41.  
  42.  
  43.             /*
  44.              ниже условие делает то же самое что и на 30 строчке условие, но уже с CountThreads
  45.              */
  46.             if (!int.TryParse(input,out CountThreads) || CountThreads <= 1)
  47.             {
  48.                 CountThreads = 1;
  49.                 Console.ForegroundColor = ConsoleColor.Red;
  50.                 Console.WriteLine($"Input error. count threads - {CountThreads}");
  51.                 Console.ResetColor();
  52.             }
  53.             /*
  54.              * ниже условие проверяет, чтобы количество потоков не было больше количества элементов
  55.              * если все таки больше, то количество потоков становится равна количеству элементов в массиве
  56.              */
  57.             if (CountThreads > CountElements)
  58.             {
  59.                 CountThreads = CountElements;
  60.                 Console.ForegroundColor = ConsoleColor.Red;
  61.                 Console.WriteLine($"Threads count bigger then count elements. Threads count - {CountThreads}");
  62.                 Console.ResetColor();
  63.             }
  64.             subArrayLen = CountElements / CountThreads + 1; //Делим количество элементов на количество потоков, таким образом мы найдем длину одной части массива
  65.             Console.WriteLine("Fill array A:");
  66.             FillArray(ref A); // Вызов метода, который делает пользовательский ввод массива А
  67.             Console.WriteLine("Fill array C:");
  68.             FillArray(ref C); // Вызов метода, который делает пользовательский ввод массива С
  69.             Console.WriteLine("A:");
  70.             ShowArray(A); // Вызов метода, который показывает все элементы массива А
  71.             Console.WriteLine("\nC:");
  72.             ShowArray(C); // Вызов метода, который показывает все элементы массива С
  73.             Thread[] threads = new Thread[CountThreads]; //Массив потоков
  74.  
  75.             for (int i = 0; i < CountThreads; i++) // Цикл запускает все потоки
  76.             {
  77.                 /*
  78.                  PartArray хранит в себе StartIndex и EndIndex
  79.                  StartIndex и EndIndex - это начальный и конечный индекс части, который пройдет поток
  80.                  123 | 456 | 789 | 0 - элементы массива разделенные символом - '|'. Это я разделил части, как видишь части длиной в 3 элемента, это наш subArrayLen
  81.                  012   345   678   9 - это индексы элементов, первая часть будет хранить в себе: StartIndex = 0 | EndIndex = 2
  82.                                        вторая часть будет хранить в себе: StartIndex = 3 | EndIndex = 5
  83.                  */
  84.                 PartArray partArray = new PartArray
  85.                 {
  86.                     StartIndex = i * subArrayLen,
  87.                     EndIndex = (i + 1) * subArrayLen
  88.                 };
  89.  
  90.                 if (partArray.EndIndex > CountElements) //Проверяет, чтобы конечный индекс не был больше чем элементов в массиве, т.к будет ошибка выхода за границы массива
  91.                     partArray.EndIndex = CountElements;
  92.                 threads[i] = new Thread(() => GetProductNumbers(partArray)); //Передать в поток метод, который запустится при запуске потока
  93.                 threads[i].Name = $"Поток№{i + 1}"; //Дать имя потоку
  94.                 threads[i].Start(); // запуск потока
  95.             }
  96.             Console.WriteLine();
  97.  
  98.             foreach (Thread thread in threads) // Цикл проходит по потокам и следующая итерация пойдет, только тогда, когда поток закончит свою работу
  99.             {
  100.                 Console.WriteLine($"{thread.Name} - on");
  101.                 thread.Join(); //У потока вызывается метод ожидания завершения
  102.                 Console.WriteLine($"{thread.Name} - off");
  103.             }
  104.             Console.WriteLine($"Result of product: {Result}"); //Вывод результата
  105.         }
  106.  
  107.         private static void FillArray(ref int[] A) //метод, который делает пользовательский ввод массива
  108.         {
  109.             Random random = new Random();
  110.             /*
  111.              Делает запрос на заполнения элемента
  112.              если пользователь не то ввел, то введется рандомное значение в элемент массива
  113.              и сообщит пользователю об этом
  114.              */
  115.             for (int i = 0; i < A.Length; i++)
  116.             {
  117.                 Console.Write($"{i + 1} element:");
  118.  
  119.                 if (!int.TryParse(Console.ReadLine(), out A[i]))
  120.                 {
  121.                     A[i] = random.Next(1, 10);
  122.                     Console.ForegroundColor = ConsoleColor.Red;
  123.                     Console.WriteLine($"Input error. element - {A[i]}");
  124.                     Console.ResetColor();
  125.                 }
  126.             }
  127.         }
  128.  
  129.         private static void ShowArray(int[] array) //метод, показывающий все элементы массива
  130.         {
  131.             foreach (int item in array) //Цикл полного перебора элементов
  132.                 Console.Write($"{item} ");
  133.         }
  134.  
  135.         private static void GetProductNumbers(PartArray partArray) //Потоковый метод. Он проходится по переданной части массива, и делает расчеты
  136.         {
  137.             int start = partArray.StartIndex; // локальная переменная берет начальный индекс части
  138.             int end = partArray.EndIndex; // локальная переменная берет конечный индекс части
  139.  
  140.             /*
  141.              * сам цикл который проходит по части массива(PartArray)
  142.              */
  143.             for (int i = start; i < end; i++)
  144.                 lock (Locker)
  145.                     Result += A[i] * C[i]; //умножается элемент A[i] на C[i] и суммируется к полю Result
  146.         }
  147.     }
  148.  
  149.     class PartArray //класс хранящий часть массива
  150.     {
  151.         public int StartIndex;
  152.         public int EndIndex;
  153.     }
  154. }
Advertisement
Add Comment
Please, Sign In to add comment