using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace CourseWork_code { #region Ініціалізація головних змінних в проекті class Shared { public static int N = 8; public static int H = N / 4; public static int[] A = new int[N]; public static int[] B = new int[N]; public static int[] Z = new int[N]; public static int[,] MC = new int[N, N]; public static int[,] MD = new int[N, N]; public static int[,] CalcMO = new int[N, N]; public static int[] CalcMP = new int[N]; public static Semaphore T1Data = new Semaphore(4, 10); public static Semaphore T2Data = new Semaphore(4, 10); public static Semaphore T3Data = new Semaphore(4, 10); public static Semaphore T4Data = new Semaphore(4, 10); public static Semaphore T1Copy = new Semaphore(4, 10); public static Semaphore T2Copy = new Semaphore(4, 10); public static Semaphore T3Copy = new Semaphore(4, 10); public static Semaphore T4Copy = new Semaphore(4, 10); public static Semaphore T1Release = new Semaphore(4, 10); public static Semaphore T2Release = new Semaphore(4, 10); public static Semaphore T3Release = new Semaphore(4, 10); public static Semaphore T4Release = new Semaphore(4, 10); public static Semaphore T1OutputData = new Semaphore(10, 10); } #endregion class T1 { public Thread thread_1; public T1(string name) { thread_1 = new Thread(new ThreadStart(this.Run)); thread_1.Name = name; thread_1.Start(); } void Run() { Console.WriteLine("\nFirst thread started!"); Console.WriteLine($"{thread_1.Name} начинает вводить данные"); //Shared.Data.WaitOne(); /*#region Ініціалізація даних for (int i = 0; i < Shared.N; i++) { Shared.A[i] = 0; Shared.Z[i] = 1; } #endregion*/ Console.WriteLine($"{thread_1.Name} заканчивает ввод данных данных"); Console.WriteLine($"{thread_1.Name} отдаёт сигнал про завершения ввода другим потокам"); Shared.T1Data.Release(); Console.WriteLine($"{thread_1.Name} ждёт сигнал про завершения ввода от второго потока"); Shared.T2Data.WaitOne(); Console.WriteLine($"{thread_1.Name} получил сигнал про завершения ввода от второго потока"); Console.WriteLine($"{thread_1.Name} ждёт сигнал про завершения ввода от четвёртого потока"); Shared.T4Data.WaitOne(); Console.WriteLine($"{thread_1.Name} получил сигнал про завершения ввода от четвёртого потока"); Console.WriteLine($"{thread_1.Name} начинает копировать данные"); /*#region Копіювання даних int[] B1 = new int[Shared.H/2]; for (int i = 0; i < Shared.H/2; i++) { B1[i] = Shared.B[i]; } int[,] MC1 = new int[Shared.H/2, Shared.N]; for (int i = 0; i < Shared.H/2; i++) { for (int j = 0; j < Shared.N; j++) { MC1[i, j] = Shared.MC[i, j]; } } #endregion*/ Console.WriteLine($"{thread_1.Name} заканчивает копировать данные и отдаёт сигнал про завершение копирования другим потокам"); Shared.T1Copy.Release(); Shared.T1Copy.WaitOne(); Console.WriteLine($"{thread_1.Name} принял сигнал про завершение копирования от первого потока"); Console.Write($"{thread_1.Name} осуществляет расчёты задачи"); /*#region Обчислення задачі int[,] CalcMO1 = new int[Shared.H/2, Shared.N]; for (int t = 0; t < Shared.H/2; t++) { for (int i = 0; i < Shared.H/2; i++) { for (int j = 0; j < Shared.N; j++) { CalcMO1[i, j] += MC1[i, t] * Shared.MD[i, j]; } } } int[] CalcMP1 = new int[Shared.N]; for (int i = 0; i < Shared.H/2; i++) { for (int j = 0; j < Shared.N; j++) { CalcMP1[i] += B1[i] * CalcMO1[i, j]; } } for (int i = 0; i < Shared.H/2; i++) { Shared.A[i] = CalcMP1[i] + Shared.Z[i]; } #endregion*/ Console.WriteLine($"{thread_1.Name} закончил считать и отдаёт об этом сигнал другим потокам"); Shared.T1Release.Release(); //Shared.T1OutputData.WaitOne(); /*#region Вивід даних Console.Write("A = "); for (int i = 0; i < Shared.N; i++) { Console.Write($"{Shared.A[i]} "); } #endregion*/ //Shared.T1OutputData.Release(); Console.WriteLine("\nFirst thread finished!"); } } class T2 { public Thread thread_2; public T2(string name) { thread_2 = new Thread(new ThreadStart(this.Run)); thread_2.Name = name; thread_2.Start(); } void Run() { Console.Write("\nSecond thread started!"); //Shared.Data.WaitOne(); //Shared.Copy.WaitOne(); /*#region Ініціалізація даних for (int i = 0; i < Shared.N; i++) { Shared.B[i] = 1; } for (int i = 0; i < Shared.N; i++) { for (int j = 0; j < Shared.N; j++) { Shared.MD[i, j] = 1; } } #endregion*/ Console.WriteLine($"{thread_2.Name} начинает вводить данные"); Console.WriteLine($"{thread_2.Name} заканчивает ввод данных данных"); Console.WriteLine($"{thread_2.Name} отдаёт сигнал про завершения ввода другим потокам"); Shared.T2Data.Release(); //Shared.T2Copy.WaitOne(); /*#region Копіювання даних int[] B2 = new int[Shared.H]; for (int i = Shared.H/2; i < Shared.H*2; i++) { B2[i] = Shared.B[i]; }*/ Console.WriteLine($"{thread_2.Name} ждёт сигнал про завершения ввода от четвёртого потока"); Shared.T4Data.WaitOne(); Console.WriteLine($"{thread_2.Name} получил сигнал про завершения ввода от четвёртого потока"); Console.WriteLine($"{thread_2.Name} начинает копировать данные"); /*int[,] MC2 = new int[Shared.H/2, Shared.N]; for (int i = Shared.H/2; i < Shared.H*2; i++) { for (int j = 0; j < Shared.N; j++) { MC2[i, j] = Shared.MC[i, j]; } } #endregion*/ Console.WriteLine($"{thread_2.Name} заканчивает копировать данные и отдаёт сигнал про завершение копирования другим потокам"); Shared.T2Copy.Release(); Console.WriteLine($"{thread_2.Name} ждёт сигнал про завершение копирования от второго потока"); Shared.T2Copy.WaitOne(); Console.WriteLine($"{thread_2.Name} принял сигнал про завершение копирования от второго потока"); Console.Write($"{thread_2.Name} осуществляет расчёты задачи"); /*#region Обчислення задачі int[,] CalcMO2 = new int[Shared.H/2, Shared.N]; for (int t = Shared.H/2; t < Shared.H*2; t++) { for (int i = Shared.H/2; i < Shared.H*2; i++) { for (int j = 0; j < Shared.N; j++) { CalcMO2[i, j] += MC2[i, t] * Shared.MD[t, j]; } } } int[] CalcMP2 = new int[Shared.H/2]; for (int i = Shared.H/2; i < Shared.H*2; i++) { for (int j = 0; j < Shared.N; j++) { CalcMP2[i] += B2[i] * CalcMO2[i, j]; } } for (int i = Shared.H/2; i < Shared.H*2; i++) { Shared.A[i] = CalcMP2[i] + Shared.Z[i]; } #endregion*/ Console.WriteLine($"{thread_2.Name} закончил считать и отдаёт об этом сигнал другим потокам"); Shared.T2Release.Release(); Console.WriteLine("\nSecond thread finished!"); /*Console.Write("A = "); for (int i = Shared.H/2; i < Shared.H*2; i++) { Console.Write($"{Shared.A[i]} "); }*/ } } class T3 { public Thread thread_3; public T3(string name) { thread_3 = new Thread(new ThreadStart(this.Run)); thread_3.Name = name; thread_3.Start(); } void Run() { Console.Write("\nThird thread started!"); Console.WriteLine($"{thread_3.Name} ждёт сигнал про завершения ввода от второго потока"); Shared.T2Data.WaitOne(); Console.WriteLine($"{thread_3.Name} получил сигнал про завершения ввода от второго потока"); Console.WriteLine($"{thread_3.Name} ждёт сигнал про завершения ввода от четвёртого потока"); Shared.T4Data.WaitOne(); Console.WriteLine($"{thread_3.Name} получил сигнал про завершения ввода от четвёртого потока"); /*#region Копіювання даних int[] B3 = new int[Shared.H/2]; for (int i = Shared.H*2; i < Shared.H*3; i++) { B3[i] = Shared.B[i]; }*/ Console.WriteLine($"{thread_3.Name} начинает копировать данные"); Console.WriteLine($"{thread_3.Name} заканчивает копировать данные и отдаёт сигнал про завершение копирования другим потокам"); Shared.T3Copy.Release(); Console.WriteLine($"{thread_3.Name} ждёт сигнал про завершение копирования от третьего потока"); Shared.T3Copy.WaitOne(); Console.WriteLine($"{thread_3.Name} принял сигнал про завершение копирования от третьего потока"); /*int[,] MC3 = new int[Shared.H/2, Shared.N]; for (int i = Shared.H*2; i < Shared.H*3; i++) { for (int j = 0; j < Shared.N; j++) { MC3[i, j] = Shared.MC[i, j]; } } #endregion*/ Console.Write($"{thread_3.Name} осуществляет расчёты задачи"); //Shared.T3Release.Release(); //Shared.T1Data.WaitOne(); //Shared.T4Data.WaitOne(); /*#region Обчислення задачі int[,] CalcMO3 = new int[Shared.H/2, Shared.N]; for (int t = Shared.H*2; t < Shared.H*3; t++) { for (int i = Shared.H*2; i < Shared.H*3; i++) { for (int j = 0; j < Shared.N; j++) { CalcMO3[i, j] += MC3[i, t] * Shared.MD[t, j]; } } } int[] CalcMP3 = new int[Shared.H/2]; for (int i = Shared.H*2; i < Shared.H*3; i++) { for (int j = 0; j < Shared.N; j++) { CalcMP3[i] += B3[i] * CalcMO3[i, j]; } } for (int i = Shared.H*2; i < Shared.H*3; i++) { Shared.A[i] = CalcMP3[i] + Shared.Z[i]; } #endregion*/ Console.WriteLine($"{thread_3.Name} закончил считать и отдаёт об этом сигнал другим потокам"); Shared.T3Release.Release(); Console.WriteLine("\nThird thread finished!"); /*Console.Write("A = "); for (int i = 0; i < Shared.N; i++) { Console.Write($"{Shared.A[i]} "); }*/ } } class T4 { public Thread thread_4; public T4(string name) { thread_4 = new Thread(new ThreadStart(this.Run)); thread_4.Name = name; thread_4.Start(); } void Run() { Console.Write("\nFourth thread started!"); Console.WriteLine($"{thread_4.Name} начинает вводить данные"); Console.WriteLine($"{thread_4.Name} заканчивает ввод данных данных"); Console.WriteLine($"{thread_4.Name} отдаёт сигнал про завершения ввода другим потокам"); /*#region Ініціалізація даних for (int i = 0; i < Shared.N; i++) { for (int j = 0; j < Shared.N; j++) { Shared.MC[i, j] = 1; } } #endregion*/ Shared.T4Data.Release(); /*Console.WriteLine($"{thread_4.Name} ждёт сигнал про завершения ввода от первого потока"); Shared.T1Data.WaitOne(); Console.WriteLine($"{thread_4.Name} получил сигнал про завершения ввода от первого потока");*/ Console.WriteLine($"{thread_4.Name} ждёт сигнал про завершения ввода от второго потока"); Shared.T2Data.WaitOne(); Console.WriteLine($"{thread_4.Name} получил сигнал про завершения ввода от второго потока"); /*#region Копіювання даних int[] B4 = new int[Shared.H/2]; for (int i = Shared.H*3; i < Shared.H*4; i++) { B4[i] = Shared.B[i]; }*/ //Shared.T4Data.WaitOne(); /*int[,] MC4 = new int[Shared.H/2, Shared.N]; for (int i = Shared.H*3; i < Shared.H*4; i++) { for (int j = 0; j < Shared.N; j++) { MC4[i, j] = Shared.MC[i, j]; } } #endregion*/ Console.WriteLine($"{thread_4.Name} начинает копировать данные"); Shared.T4Copy.Release(); Console.WriteLine($"{thread_4.Name} заканчивает копировать данные и отдаёт сигнал про завершение копирования другим потокам"); Shared.T4Copy.WaitOne(); Console.WriteLine($"{thread_4.Name} принял сигнал про завершение копирования от четвёртого потока"); /*#region Обчислення задачі int[,] CalcMO4 = new int[Shared.H/2, Shared.N]; for (int t = Shared.H*3; t < Shared.H*4; t++) { for (int i = Shared.H*3; i < Shared.H*4; i++) { for (int j = 0; j < Shared.N; j++) { CalcMO4[i, j] += MC4[i, t] * Shared.MD[t, j]; } } } int[] CalcMP4 = new int[Shared.H/2]; for (int i = Shared.H*3; i < Shared.H*4; i++) { for (int j = 0; j < Shared.N; j++) { CalcMP4[i] += B4[i] * CalcMO4[i, j]; } } for (int i = Shared.H*3; i < Shared.H*4; i++) { Shared.A[i] = CalcMP4[i] + Shared.Z[i]; } #endregion*/ Console.Write($"{thread_4.Name} осуществляет расчёты задачи"); Console.WriteLine($"{thread_4.Name} закончил считать и отдаёт об этом сигнал другим потокам"); Shared.T4Release.Release(); Console.WriteLine("\nFourth thread finished!"); /*Console.Write("A = "); for (int i = Shared.H*3; i < Shared.H*4; i++) { Console.Write($"{Shared.A[i]} "); }*/ } } class Program { static void Main(string[] args) { Shared shared = new Shared(); Console.WriteLine("Main started"); T1 one = new T1("first"); T2 two = new T2("second"); T3 three = new T3("third"); T4 four = new T4("fourth"); one.thread_1.Join(); two.thread_2.Join(); three.thread_3.Join(); four.thread_4.Join(); Console.WriteLine("\nMain finished"); Console.ReadLine(); } } }