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();
}
}
}