ПКРПСиБД LAB5 Бочаров И.А. (Лабораторная работа 5)
Описание файла
Файл "ПКРПСиБД LAB5 Бочаров И.А." внутри архива находится в папке "Лабораторная работа 5". Документ из архива "Лабораторная работа 5", который расположен в категории "". Всё это находится в предмете "распределённые ис и базы данных" из 9 семестр (1 семестр магистратуры), которые можно найти в файловом архиве НИУ «МЭИ» . Не смотря на прямую связь этого архива с НИУ «МЭИ» , его также можно найти и в других разделах. Архив можно найти в разделе "лабораторные работы", в предмете "распределённые ис и базы данных" в общих файлах.
Онлайн просмотр документа "ПКРПСиБД LAB5 Бочаров И.А."
Текст из документа "ПКРПСиБД LAB5 Бочаров И.А."
Национальный исследовательский институт
Московский Энергетический Институт (Технический Университет)
Институт автоматики и вычислительной техники
Кафедра Прикладной математики
Лабораторная работа №5
по дисциплине:
Проектирование крупных распределенных программных систем и баз данных
тема: «Разработка одного из шаблонов параллельного программирования»
вариант №5 – «Scheduler/Планировщик»
Выполнил:
Бочаров Иван Андреевич
Проверил:
к.т.н., доц. Куриленко Иван Евгеньевич
Москва
2012 г.
Шаблон проектирования «Планировщик»
Категория шаблона
Шаблон проектирования «Планировщик» относится к шаблонам параллельного программирования.
Описание шаблона
Планировщик - паттерн параллельного программирования, который используется для обеспечения явного контроля за ситуацией, когда разные потоки могут выполнять куски однопоточного кода (операции записи в файл и т.д.).
Суть паттерна заключается в создании объекта, который явным образом ставит в очередь ожидающие ресурс потоки.
Уместность применения
Шаблон следует применять, если:
-
Несколько потоков могут потребовать доступа к ресурсу одновременно, и только один из них может в конкретный момент осуществить доступ к ресурсу
-
Требуется обеспечение доступа потоков к ресурсу в строго определенном порядке
Преимущества шаблона
При использовании шаблона «Планировщик» объект планировщика независим от политики, по которой упорядочиваются потоки, что упрощает повторное использование кода.
Реализация
MobileAccount.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SchedulerPattern
{
class MobileAccount
{
private static int transactionID;
private Scheduler scheduler = new Scheduler();
private int balance = 0;
public void Handle(Transaction transaction)
{
int id = ++transactionID;
try
{
Console.WriteLine(String.Format(@"Transaction #{0}: enter scheduler", id));
scheduler.Enter(transaction);
Console.WriteLine(String.Format(@"Transaction #{0}: start handling", id));
try
{
transaction.Do(id);
balance += transaction.Chng;
}
finally
{
scheduler.Done();
Console.WriteLine(String.Format(@"Transaction #{0}: done! Account balance is {1}", id, balance));
}
}
catch (Exception) { }
}
}
}
Scheduler.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace SchedulerPattern
{
class Scheduler
{
private AutoResetEvent evnt = new AutoResetEvent(false);
private Thread runningThread;
private Dictionary
public void Enter(IOrdering s)
{
var thisThread = Thread.CurrentThread;
lock (this)
{
if (runningThread == null)
{
runningThread = thisThread;
return;
}
waiting.Add(thisThread, s);
}
lock (thisThread)
{
while (thisThread != runningThread)
{
evnt.WaitOne();
evnt.Set();
Thread.Sleep(1);
}
evnt.Reset();
}
lock (this)
{
waiting.Remove(thisThread);
}
}
public void Done()
{
lock (this)
{
if (runningThread != Thread.CurrentThread)
throw new ThreadStateException(@"Wrong Thread");
int waitCount = waiting.Count;
if (waitCount <= 0)
{
runningThread = null;
}
else if (waitCount == 1)
{
runningThread = waiting.First().Key;
waiting.Remove(runningThread);
evnt.Set();
}
else
{
var next = waiting.First();
foreach (var wait in waiting)
{
if (wait.Value.ScheduleBefore(next.Value))
{
next = wait;
}
}
runningThread = next.Key;
evnt.Set();
}
}
}
}
static partial class ConvertTo
{
public static KeyValuePair
{
foreach (var item in collection)
{
return item;
}
throw new ArgumentException();
}
}
}
Transaction.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace SchedulerPattern
{
class Transaction : IOrdering
{
private static DateTime mTime = DateTime.Now;
private DateTime time;
public DateTime Time { get { return time; } }
private int chng;
public int Chng
{
get { return chng; }
}
public Transaction(int chng)
{
mTime = mTime.AddSeconds(1);
time = mTime;
this.chng = chng;
}
public void Do(int id)
{
Console.WriteLine(String.Format(@"Transaction #{0}: Start : {1} : Balance change: {2} roubles", id, time, chng));
Thread.Sleep(1000);
Console.WriteLine(String.Format(@"Transaction #{0}: Finish : {1} : Balance change: {2} roubles", id, time, chng));
}
public Boolean ScheduleBefore(IOrdering s)
{
if (s is Transaction)
{
var otherTransaction = (Transaction)s;
return (this.Time < otherTransaction.Time);
}
return false;
}
}
}
IOrdering.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SchedulerPattern
{
interface IOrdering
{
Boolean ScheduleBefore(IOrdering s);
}
}
UML-диаграмма классов
Диаграмма последовательности
Литература
-
http://en.wikipedia.org/wiki/Scheduler_pattern
-
http://ru.wikipedia.org/wiki/Scheduler