Зависает поток - C#
Формулировка задачи:
Есть код, реализующий доступ "читателей" и "писателей" к буферу
Используются сигнальные сообщения.
Дойдя до строки
Дальше код не выполняется, ошибок никаких не выдается. пробовал отладчиком - везде наставил точки, но никуда и не заходит
foreach (var t in writers)
t.Join();using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
private static String buffer = null;
private static bool finish = false;
static void Main(string[] args)
{
Console.Write("Количество читателей: ");
var CountReder = Convert.ToInt32(Console.ReadLine());
Console.Write("Количество писателей: ");
int CountWriter = Convert.ToInt32(Console.ReadLine());
var readers = new Thread[CountReder];
var writers = new Thread[CountWriter];
var Event = new AutoResetEvent[2];
Event[0] = new AutoResetEvent(false);
Event[1] = new AutoResetEvent(false);
var sw = new Stopwatch();
sw.Start();
for (var i = 0; i < readers.Length; i++)
{
readers[i] = new Thread(Reader);
readers[i].Start(Event);
}
for (var i = 0; i < writers.Length; i++)
{
writers[i] = new Thread(Writer);
writers[i].Start(Event);
}
foreach (var t in writers)
t.Join();
finish = true;
foreach (var t in readers)
t.Join();
sw.Stop();
TimeSpan ts = sw.Elapsed;
Console.WriteLine("Общее время: {0} миллисекунд", ts.TotalMilliseconds);
Console.ReadKey();
}
static void Reader(object state)
{
object[] data = (object[])state;
var evFull = data[0] as AutoResetEvent;
var evEmpty = data[1] as AutoResetEvent;
var msg = new List<string>();
while (true)
{
evFull.WaitOne();
// Сигнал о завершении работы
if (finish) break;
msg.Add(buffer);
evEmpty.Set();
}
}
static void Writer(object state)
{
object[] data = (object[]) state;
var evFull = data[0] as AutoResetEvent;
var evEmpty = data[1] as AutoResetEvent;
string[] msg =
{
"первое сообщение",
"второе сообщение",
"третие сообщение"
};
int i = 0;
while (i < msg.Length)
{
evEmpty.WaitOne();
buffer = msg[i++];
evFull.Set();
}
}
}
}Решение задачи: «Зависает поток»
textual
Листинг программы
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace lab3
{
class Program
{
//список, куда потоки-читатели записывают прочтенную информацию с буфера
static List<string> bufferHistory;
static string buffer;
static Thread[] writers, readers;
static bool isWriteCompleted;
//общее количество информации, которую надо записать
static int dataCount = 10000;
static int writersCount = 4, readersCount = 4;
static int dataPerThread = dataCount / writersCount;
static AutoResetEvent bufferEmpty, bufferFull;
static void Main(string[] args)
{
DateTime from = DateTime.Now;
bufferHistory = new List<string>();
//устанавливаем флаг, что буфер пуст
bufferEmpty = new AutoResetEvent(true);
//что буфер неполон
bufferFull = new AutoResetEvent(false);
writers = new Thread[writersCount];
readers = new Thread[readersCount];
//создание потоков-писателей
for (int i = 0; i < writersCount; i++)
{
Thread writer = new Thread(WriterThread);
writer.Name = "W" + i;
writers[i] = writer;
}
//создание потоков-читателей
for (int i = 0; i < readersCount; i++)
{
Thread reader = new Thread(ReaderThread);
readers[i] = reader;
}
//запуск потоков-писателей
for (int i = 0; i < writersCount; i++)
{
writers[i].Start();
}
//запуск потоков-читателей
for (int i = 0; i < readersCount; i++)
{
readers[i].Start();
}
//ожидание выполнения потоков-писателей
for (int i = 0; i < writersCount; i++)
{
writers[i].Join();
}
isWriteCompleted = true;
bufferFull.Set();
//ожидание выполнения потоков-читателей
for (int i = 0; i < readersCount; i++)
{
readers[i].Join();
}
DateTime to = DateTime.Now;
double cur = (to - from).TotalMilliseconds;
//foreach (string str in bufferHistory)
// Console.WriteLine(str);
Console.WriteLine("Threads: {0}/{1}, perThread: {2} = {3}", writersCount, readersCount, dataPerThread, cur);
}
static void WriterThread()
{
int i = 0;
while (i < dataPerThread)
{
bufferEmpty.WaitOne();
buffer = Thread.CurrentThread.Name + "_" + i;
i++;
bufferFull.Set();
}
}
static void ReaderThread()
{
while (!isWriteCompleted)
{
bufferFull.WaitOne();
if (isWriteCompleted)
{
bufferFull.Set();
break;
}
bufferHistory.Add(buffer);
bufferEmpty.Set();
}
}
}
}