GreenMap

Лабораторная 4 по ААС

Apr 24th, 2020
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.02 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7.  
  8. namespace MultithreadedWorkWithMultiElementBuffer
  9. {
  10.     static class Program
  11.     {
  12.         static int nReader = 2;
  13.         static int nWriter = 3;
  14.         static int nMessanger = 10000;
  15.         const int nBuffer = 10;
  16.         static int iR, iW;
  17.         static Task[] tReaders, tWriters;
  18.         static string[] buffer;
  19.         static bool finish;
  20.         static bool bFull;
  21.         static bool bEmpty;
  22.         static int[] WriteIndexCopy;
  23.         static int[] ReadIndexCopy;
  24.         static int[] WriterPriority;
  25.         static int[] ReaderPriority;
  26.         static double[] timeWriter;
  27.         static double[] timeReader;
  28.         static int[] countMessageWriter;
  29.         static int[] countMessageReader;
  30.         static int[] nReaderList = { 2, 4 };
  31.         static int[] nWriterList = { 3, 6 };
  32.         static int[] nMessangerList = { 10000, 20000, 50000 };
  33.  
  34.         static void Main(string[] args)
  35.         {
  36.             for(int i = 0; i < nReaderList.Length; i++)
  37.             {
  38.                 nReader = nReaderList[i];
  39.                 for(int j = 0; j < nWriterList.Length; j++)
  40.                 {
  41.                     nWriter = nWriterList[j];
  42.                     for(int k = 0; k < nMessangerList.Length; k++)
  43.                     {
  44.                         nMessanger = nMessangerList[k];
  45.                         Start();
  46.                     }
  47.                 }
  48.             }
  49.             Thread.Sleep(50000);
  50.         }
  51.         static void Start()
  52.         {
  53.             finish = false;
  54.             bFull = false;
  55.             bEmpty = true;
  56.             iR = 0;
  57.             iW = 0;
  58.             timeWriter = new double[nWriter];
  59.             timeReader = new double[nReader];
  60.             countMessageWriter = new int[nWriter];
  61.             countMessageReader = new int[nReader];
  62.             WriteIndexCopy = new int[nWriter];
  63.             ReadIndexCopy = new int[nReader];
  64.             WriterPriority = new int[nWriter];
  65.             ReaderPriority = new int[nReader];
  66.             buffer = new string[nBuffer];
  67.  
  68.             for (int i = 0; i < ReadIndexCopy.Length; i++)
  69.                 ReadIndexCopy[i] = -1;
  70.             for (int i = 0; i < WriteIndexCopy.Length; i++)
  71.                 WriteIndexCopy[i] = -1;
  72.  
  73.             Random rnd = new Random();
  74.             for (int i = 0; i < nWriter; i++)
  75.                 WriterPriority[i] = rnd.Next(nWriter);
  76.             for (int i = 0; i < nReader; i++)
  77.                 ReaderPriority[i] = rnd.Next(nReader);
  78.  
  79.             Manager();
  80.  
  81.             Console.WriteLine("Thread priorities are set randomly. Size of the ring buffer is: " + Convert.ToString(nBuffer));
  82.             Console.WriteLine("Number of readers: " + Convert.ToString(nReader) + ". Number of writers: " + Convert.ToString(nWriter) + ". Number of messages every writer: " + Convert.ToString(nMessanger));
  83.  
  84.             for (int i = 0; i < nWriter; i++)
  85.                 Console.WriteLine("Writer " + Convert.ToString(i) + " recorded " + Convert.ToString(countMessageWriter[i]) + " messages in " + Convert.ToString(timeWriter[i]) + " msec.");
  86.             Console.WriteLine("Total recorded messages is " + Convert.ToString(countMessageWriter.Sum()));
  87.             for (int i = 0; i < nReader; i++)
  88.                 Console.WriteLine("Reader " + Convert.ToString(i) + " read " + Convert.ToString(countMessageReader[i]) + " messages in " + Convert.ToString(timeReader[i]) + " msec.");
  89.             Console.WriteLine("Total readed messages is " + Convert.ToString(countMessageReader.Sum()));
  90.         }
  91.  
  92.         static void ReaderThread(int iReader, ManualResetEventSlim evReadyToRead, ManualResetEventSlim evStartReading)
  93.         {
  94.             DateTime dStart, dStop;
  95.             dStart = DateTime.Now;
  96.             var Messages = new List<string>();
  97.             countMessageReader[iReader] = 0;
  98.             while (!finish)
  99.             {
  100.                 evReadyToRead.Set();
  101.                 evStartReading.Wait();
  102.                 if (finish && evReadyToRead.IsSet) break;
  103.                 int k = ReadIndexCopy[iReader];
  104.                 Messages.Add(buffer[k]);
  105.                 countMessageReader[iReader]++;
  106.                 bFull = false;
  107.                 evStartReading.Reset();
  108.                 ReadIndexCopy[iReader] = -1;
  109.             }
  110.             dStop = DateTime.Now;
  111.             timeReader[iReader] = new double();
  112.             timeReader[iReader] = (dStop - dStart).TotalMilliseconds;
  113.         }
  114.         static void WriterThread(int iWriter, ManualResetEventSlim evReadyToWrite, ManualResetEventSlim evStartWriting)
  115.         {
  116.             DateTime dStart, dStop;
  117.             dStart = DateTime.Now;
  118.             countMessageWriter[iWriter] = 0;
  119.             string[] Messages = new string[nMessanger];
  120.             for (int i = 0; i < Messages.Length; i++)
  121.             {
  122.  
  123.                 Messages[i] = "{iWriter}_{i}";
  124.             }
  125.             int j = 0;
  126.             while (j < Messages.Length)
  127.             {
  128.                 evReadyToWrite.Set();
  129.                 evStartWriting.Wait();
  130.                 int k = WriteIndexCopy[iWriter];
  131.                 buffer[k] = Messages[j++];
  132.                 countMessageWriter[iWriter]++;
  133.                 bEmpty = false;
  134.                 evStartWriting.Reset();
  135.                 WriteIndexCopy[iWriter] = -1;
  136.             }
  137.             dStop = DateTime.Now;
  138.             timeWriter[iWriter] = (dStop - dStart).TotalMilliseconds;
  139.         }
  140.         static void Manager()
  141.         {
  142.             ManualResetEventSlim[] evStartReading, evStartWriting;
  143.             ManualResetEventSlim[] evReadyToRead, evReadyToWrite;
  144.             evReadyToRead = new ManualResetEventSlim[nReader];
  145.             evStartReading = new ManualResetEventSlim[nReader];
  146.             evReadyToWrite = new ManualResetEventSlim[nWriter];
  147.             evStartWriting = new ManualResetEventSlim[nWriter];
  148.             tReaders = new Task[nReader];
  149.             tWriters = new Task[nWriter];
  150.             for (int i = 0; i < tReaders.Length; i++)
  151.             {
  152.                 evReadyToRead[i] = new ManualResetEventSlim(false);
  153.                 evStartReading[i] = new ManualResetEventSlim(false);
  154.                 int i_copy = i;
  155.                 tReaders[i] = new Task(() =>
  156.                 {
  157.                     ReaderThread(i_copy, evReadyToRead[i_copy], evStartReading[i_copy]);
  158.                 });
  159.                 tReaders[i].Start();
  160.             }
  161.             for (int i = 0; i < tWriters.Length; i++)
  162.             {
  163.                 evReadyToWrite[i] = new ManualResetEventSlim(false);
  164.                 evStartWriting[i] = new ManualResetEventSlim(false);
  165.                 int i_copy = i;
  166.                 tWriters[i] = new Task(() =>
  167.                 {
  168.                     WriterThread(i_copy, evReadyToWrite[i_copy], evStartWriting[i_copy]);
  169.                 });
  170.                 tWriters[i].Start();
  171.             }
  172.             while (!finish)
  173.             {
  174.                 if (!bFull && !ReadIndexCopy.Contains(iW))
  175.                 {
  176.                     int iWriter = GetWriter(evReadyToWrite);
  177.                     if (iWriter != -1)
  178.                     {
  179.  
  180.                         evReadyToWrite[iWriter].Reset();
  181.                         WriteIndexCopy[iWriter] = iW;
  182.                         evStartWriting[iWriter].Set();
  183.                         iW = (iW + 1) % nBuffer;
  184.                         if (iW == iR) bFull = true;
  185.                     }
  186.                 }
  187.                 if (!bEmpty && !WriteIndexCopy.Contains(iR))
  188.                 {
  189.                     int iReader = GetReader(evReadyToRead);
  190.                     if (iReader != -1)
  191.                     {
  192.  
  193.                         evReadyToRead[iReader].Reset();
  194.                         ReadIndexCopy[iReader] = iR;
  195.                         evStartReading[iReader].Set();
  196.                         iR = (iR + 1) % nBuffer;
  197.                         if (iR == iW) bEmpty = true;
  198.                     }
  199.                 }
  200.                 if (tWriters.All(t => t.IsCompleted) && bEmpty)
  201.                     finish = true;
  202.             }
  203.             foreach (var sr in evStartReading.Where(e => !e.IsSet))
  204.                 sr.Set();
  205.             Task.WaitAll(tReaders);
  206.         }
  207.         static int GetWriter(ManualResetEventSlim[] evReadyToWrite)
  208.         {
  209.             var ready = new List<int>();
  210.             for (int i = 0; i < nWriter; i++)
  211.                 if (evReadyToWrite[i].IsSet)
  212.                     ready.Add(i);
  213.             if (ready.Count == 0)
  214.                 return -1;
  215.             return ready.OrderBy(i => WriterPriority[i]).First();
  216.         }
  217.         static int GetReader(ManualResetEventSlim[] evReadyToRead)
  218.         {
  219.             var ready = new List<int>();
  220.             for (int i = 0; i < nReader; i++)
  221.                 if (evReadyToRead[i].IsSet)
  222.                     ready.Add(i);
  223.             if (ready.Count == 0)
  224.                 return -1;
  225.             return ready.OrderBy(i => ReaderPriority[i]).First();
  226.         }
  227.     }
  228. }
Add Comment
Please, Sign In to add comment