Лабораторная работа 5 (ПКРПСиБД 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<Thread, IOrdering> waiting = new Dictionary<Thread, IOrdering>();


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<Thread, IOrdering> First(this Dictionary<Thread, IOrdering> collection)

{

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-диаграмма классов

Диаграмма последовательности



Литература

  1. http://en.wikipedia.org/wiki/Scheduler_pattern

  2. http://ru.wikipedia.org/wiki/Scheduler


Случайные файлы

Файл
66457.rtf
49904.rtf
witamin.doc
21524.doc
157554.doc




Чтобы не видеть здесь видео-рекламу достаточно стать зарегистрированным пользователем.
Чтобы не видеть никакую рекламу на сайте, нужно стать VIP-пользователем.
Это можно сделать совершенно бесплатно. Читайте подробности тут.