Распределенная синхронизация процессов

 















Курсовая работа

по дисциплине:

Операционные системы

Распределенная синхронизация процессов


Введение

программа сетевой интерфейс

При работе с данными на современных операционных системах остро стоит проблема в их синхронизации. Проблемы могут происходить, когда к одним и тем же данным получают доступ различные процессы. И даже не столько в случае одновременного изменения. Чтение данных в одном потоке после изменения их другим тоже может давать неверный результат в целом. Так же одной из проблем может являться уменьшение производительности работы в целом. Синхронизация - это некоторые дополнительные издержки.

Цель работы является разработка программы, создающая и запускающая несколько отдельных процессов в определённой последовательности. Информация о каждом запущенном процессе передаётся и принимается через сокеты UDP и записывается в файл.

В целом, задачей разработки являлось создание такого приложения, которое будет удалённо запускать в последовательности отдельные задачи.

В главе «Описание программ» подробно описаны теоретические особенности построения сетевого стека.

В главе «Тексты программ» находятся исходные коды на языке C# и файлы конфигурации процессов в формате INI файлов.

В главе «Выводы» даются результаты о проделанной работе.

Наиболее важными источниками знаний послужил сервис от Microsoft - MSDN, а также книга Гордеева - «Операционные системы».


Задание


Создать процессы (отдельные задачи), которые выполняются в последовательности, определяемой графом запуска в соответствии с вариантом задания. Каждая дуга графа соответствует процессу, имя дуги - имя процесса. Вершины графа - точки синхронизации процессов.

Процессы после запуска находятся в ожидании завершения предшествующих им процессов. При выполнении выводят информацию (имя процесса, время запуска и окончания работы), передают управление другим процессам и завершаются. В процессах вводится небольшая временная задержка (несколько секунд) для того, чтобы было легче отследить соответствие запусков и окончаний процессов графу запуска. Для первоначального запуска набора процессов рекомендуется использовать командный файл.

Приём и передача информации о завершении процесса осуществляется через сокеты TCP или UDP. Фактически приём-передача этой информации выступает в роли средства распределённой синхронизации процессов в IP-сети.

Необходимо предусмотреть создание необходимого числа сокетов в каждой задаче и определить корректную нумерацию портов, чтобы обмен был возможен как на локальном компьютере (local host.localdomain) так и при запуске задач на компьютерах с разными IP-адресами в пределах локальной или глобальной TCP/IP-сети. Должна быть предусмотрена возможность изменения IP-адреса компьютера при запуске процесса (ввод из командной строки, файла и т.п.). При демонстрации курсовой работы часть процессов запускается на одном, а остальные - на другом (других) компьютере (компьютерах) ЛВС.

Операционная система - Windows или Linux. Система программирования - Visual C или GNU C. Возможен гибридный вариант реализации, когда часть процессов работает под управление ОС Linux, а оставшиеся - под ОС MS Windows. В последнем случае для отладки вне вычислительной сети имеет смысл использовать эмуляторы другой ОС (CYGWIN, WINE) или виртуальные машины.

Граф синхронизации процессов. Вариант #2



Рис. 1. Граф синхронизации процессов


На графе отчётливо видно, что существует 11 дуг. Каждая дуга графа соответствует процессу. Вершины графа - точки синхронизации процессов. Имена процессов: a, b, c, d, e, f ,g, h, i, m, n.


1.Описание программ


Программа работает под управлением Windows 32 бит. Написана на C# .NET 2.0. Данные в программу поступают по сетевому стеку UDP. Исходные данные лежат в отдельных INI файлах.

Программа состоит из модуля сервера и клиента. Клиент-сервер работает одновременно на одном компьютере. Во время включения программы, проверяется - есть ли у программы родитель - в случае нахождения происходит отправка сообщения и последующая работа. В остальном случае - программа слушает и в зависимости от принятых данных отправляет сообщения. Функции локального управления используются, главным образом, для выполнения подготовительных действий, необходимых для организации взаимодействия двух программ-партнёров.


1.1Сокеты


В программе широко используются сокеты. В C# сокеты реализованы с помощью класса Socket. Класс Socket обеспечивает широкий набор методов и свойств для сетевых взаимодействий. Socket придерживается шаблона имён платформы .NET Framework для синхронный методов. Для протокола UDP, нет необходимости в отслеживании подключений. Метод Accept обрабатывает любые входящие запросы на подключение и возвращает объект Socket, который может использоваться для передачи данных с удалённого узла. Объект Socket используется для вызова метода Send или Receive. Метод Bind, обращается к Listen, к которому необходимо указать локальный IP-адрес или номер порта. Если требуется произвести подключение к прослушивающему узлу, используется метод Connect. Для обмена данными метод Send или Receive. Когда приём и отправка данных завершены, используется метод Shutdown для того, чтобы отключить объект Socket. После вызова метода Shutdown происходит обращение к методу Close, чтобы освободить все связанные с объектом Socket ресурсы.

Процесс в Windows состоит из следующих компонентов:

·Структура данных, содержащая всю информацию о процессе, в том числе список открытых дескрипторов различных системных ресурсов, уникальный идентификатор процесса, различную статистическую информацию и т.д.;

·Адресное пространство - диапазон адресов виртуальной памяти, которым может пользоваться процесс;

·Исполняемая программа и данные, проецируемые на виртуальное адресное пространство процесса.

Создание Win32 процесса осуществляется вызовом одной из таких функций, как CreateProcess, CreateProcessAsUser (для Win NT/2000) и CreateProcessWithLogonW (начиная с Win2000) и происходит в несколько этапов:

·Открывается файл образа (EXE), который будет выполняться в процессе.

·Если исполняемый файл не является Win32 приложением, то ищется образ поддержки (support image) для запуска этой программы. Например, если запускается cmd.exe.

Процесс завершается если:

·Входная функция первичного потока возвратила управление.

·Один из потоков процесса вызвал функцию ExitProcess.

·Поток другого процесса вызвал функцию TerminateProcess.

·Когда процесс завершается, все User- и GDI-объекты, созданные процессом, уничтожаются, объекты ядра закрываются (если их не использует другой процесс), адресное пространство процесса уничтожается.


1.2Процессы


Процесс - это объединение нескольких потоков. А объединяет эти потоки единое виртуальное адресное пространство. В этом пространстве размещаются код и данные приложения (обычно это один exe и несколько dll-модулей). Именно единство этого пространства и делает обмен данными между потоками приложения предельно простым. Наоборот, адресные пространства различных процессов независимы и отделены друг от друга (хотя, используя проекции файла в память (memory mapped file), можно создать область памяти, которая будет доступна совместно нескольким процессам). Таким образом, процесс - это несколько потоков (как минимум один) плюс единое виртуальное адресное пространство. Поскольку все потоки процесса работают в едином адресном пространстве, обмен данными между ними крайне прост, однако при этом требуется согласовывать их работу над совместными данными. Собственно, под термином «синхронизация», как правило, имеют в виду именно согласование работы потоков, принадлежащих одному процессу. Этому и будут посвящены следующие части данной статьи. Хотя некоторые из описанных далее приёмов можно использовать и для синхронизации потоков принадлежащих разным процессам, в основном согласование их работы связано с «механизмами взаимосвязи процессов» (inter-process communications, IPC). Действительно, трудно представить ситуацию, когда нам потребовалось бы согласовывать движение потоков без необходимости обмена данными между ними. А для этого, если потоки работают в разных адресных пространствах, требуются специальные механизмы, носящие обобщённое название IPC (проекции файлов в память - один из них). Процесс - это набор потоков, работающих в едином адресном пространстве. Само по себе, адресное пространство без потоков смысла не имеет. Поэтому процесс считается завершённым, как только завершатся все его потоки.


2.Тексты программ


Интерфейс программы разработан с помощью Windows Forms. Интерфейс состоит из главного окна, на котором отображены данные о пользовательских настройках запуска процессов. При загрузке программы происходит заполнение окна конфигурационными данными. После загрузки, программа ищет «потомков» по сети и подключается к ним. Когда подключение установлено - программа проверяет, какой процесс следует запустить, в случае нахождения данных о процессе - запускает его. После завершения процесса - выполнившая программа останавливается. А «родителем» становится программа, которая приняла все данные. «Родитель» начинает процесс поиска своих «потомков». Интерфейс достаточно прост. И не требует от пользователя каких-либо действий, кроме правки конфигурационного файла.


Рис. 2. Скриншот работы 4 процессов на локальном компьютере


2.1Исходный код


class WriteLog {static bool Write(string message) {{string url = @"\\fs\Study\_\ПО08\temp.txt";text = System.IO.File.AppendText(url);.WriteLine(message);.Close();

}{false;

} return true;

}

}class Client {readonly string Ip;readonly int Port;readonly string Processname;TcpClient _client;Client(string ip, int port, string processname) {= ip;= port;= processname;

if (SendData()) {.Msg("Данные успешно отправлены!");

} // Теперь подключаться к потомкам

}

private bool SendData() {

_client = new TcpClient();flag = true;{

_client.Connect(Ip, Port);[] mas = Encoding.UTF8.GetBytes(Processname);

_client.Client.Send(mas);

}{= false;

} return flag;

}

}partial class FormClient : Form {static readonly string Path = Environment.CurrentDirectory; // текущая директория

#region СпискиList<string> _childProcessname;List<string> _childsIp;List<string> _childsPort;List<string> _parentProcessname;List<string> _serverPort;List<string> _serverProcessname;

#endregionFormClient() {();();cr = new Thread(OpenPort);

cr.Start();

//Если родителей нет - подключаюсь к потомкам

if (_parentProcessname.Count == 0 && _serverProcessname.Count > 0) {processname = _serverProcessname[0];string ip = "127.0.0.1";port = int.Parse(_serverPort[0]);

new Client(ip, port, processname); //а также выполняем главные процесс А

ConnectToChild();

}

}void OpenPort() {(string t in _serverPort) {(t == "") return;{port = Convert.ToInt16(t);

//Если родители есть то открываем порт(_parentProcessname.Count != 0) {("Открываю порт " + port + " для подключения родителей");Servak(port);

}

}{("Проблема при открытие порта");

}

}

}void ConnectToChild() {("ищем потомков...");

//Если потомки есть(_childProcessname.Count != 0) {(int i = 0; i < _childsPort.Count; i++) {port = Convert.ToInt16(_childsPort[i]);ip = _childsIp[i];processname = _childProcessname[i];

Msg("подключаюсь к потомку " + processname); // Подключаемся к серверу по serverPort

try {Client(ip, port, processname); //подключаемся к потомку

}{(string.Format("Подключиться к потомку {0} не удалось", processname));

}

}

}{("Потомков нет.");

}

}static void Msg(string mesg) {(!WriteLog.Write(mesg)) {.Show("Произошла проблема с записью");

}

}void GetInfoFromINIFile() {[] directorypath = new DirectoryInfo(Path).GetFiles();

//Заполнение списков

_serverProcessname = new List<string>();

_serverPort = new List<string>();

_parentProcessname = new List<string>();

_childProcessname = new List<string>();

_childsIp = new List<string>();

_childsPort = new List<string>();

//инфо об файлах(FileInfo info in directorypath) {fullname = info.FullName;temp = new IniFile(fullname);

string[] readText = File.ReadAllLines(fullname); //временный, зранит все записи

//Читаем все строчки

foreach (string s in readText) {(s == "");(Regex.IsMatch(s, "Server")) { _serverProcessname.Add(temp.IniReadValue("Server", "Processname")); _serverPort.Add(temp.IniReadValue("Server", "Port"));

}

//Если найден Parent - добавляем (учитывая что есть 1, 2, ...)

else if (Regex.IsMatch(s, "Parent")){parentS = s.Replace("[", "").Replace("]", "");

_parentProcessname.Add(temp.IniReadValue(parentS, "Processname"));

}

//то же самое только с Child

else if (Regex.IsMatch(s, "Child")){childS = s.Replace("[", "").Replace("]", "");

//Проверка на UTF-8. Глюк возникает, в "s" вводится какая-то очень длинная

if (s.Length > 50); _childProcessname.Add(temp.IniReadValue(childS, "Processname"));

_childsIp.Add(temp.IniReadValue(childS, "Ip"));

_childsPort.Add(temp.IniReadValue(childS, "Port"));

}

}

}();

}void AddText(string text) {(text != "").Text = tbxText.Text + Environment.NewLine + text;

}void GetText() {(Environment.NewLine + "Серверы");(string server in _serverProcessname) {(server);

} (Environment.NewLine + "Айпи Серверов ");(string servPort in _serverPort) {(servPort);

}(Environment.NewLine + "Родители");(string parent in _parentProcessname) {(parent);

}(Environment.NewLine + "Потомки");(string child in _childProcessname) {(child);

}(Environment.NewLine + "Айпи детей");(string s in _childsIp) {(s);

}(Environment.NewLine + "Порты детей");(string s in _childsPort) {(s);

}

}

}class IniFile{string path;

/// <summary>

/// Конструктор класса

/// </summary>

/// <PARAM name="INIPath">Путь к INI-файлу</PARAM>IniFile(string INIPath) {= INIPath;

}

[DllImport("kernel32")]static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

[DllImport("kernel32")]static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);void IniWriteValue(string Section, string Key, string Value) {(Section, Key, Value, path);

}string IniReadValue(string section, string key) {temp = new StringBuilder(255);(section, key, "", temp,

, path);temp.ToString();

}

}class Processes {static void SendData(object data) {

FormClient.Msg("выполняется процесс " + data);

var fp = new FormPotok {Text = data.ToString()};.Show();(var millisecondsTimeout = 1; millisecondsTimeout < 100; millisecondsTimeout++ ) {.progBar.Value = millisecondsTimeout;.Sleep(millisecondsTimeout);

}.Msg("Процесс " + data + " выполнен");FormClient().ConnectToChild();//Теперь передачу на потомков

}static void StartPotoks(string name) {Thread(SendData).Start(name);

}

}Servak {Servak(int port) {

FormClient.Msg("Ожидаем запрос к подключению");

IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);newsock = new Socket(AddressFamily.InterNetwork, .Stream, ProtocolType.IP);.Bind(ipep);.Listen(10);.Msg("родитель подключен...");client = newsock.Accept();data = new byte[1024];recv = client.Receive(data);RecvString = Encoding.ASCII.GetString(data, 0, recv);

Processes.StartPotoks(RecvString);

}

}


2.2Конфигурационный файл


Процесс a

[Server]= 8881= a

[Child1]= 127.0.0.1= 8883= c

[Child2]= 127.0.0.1= 8884= d

[Child3]= 127.0.0.1= 8885= e

Процесс b

[Server]= 8882= b

[Child1]= 127.0.0.1= 8889= i

[Child2]= 127.0.0.1= 8888= h

[Child3]= 127.0.0.1= 8887= g

Процесс c

[Server]= 8883= c

[Parent1]= a

[Child1]= 127.0.0.1= 8889= i

[Child2]= 127.0.0.1= 8888= h

[Child3]= 8887= 127.0.0.1= g

Процесс n

[Server]= 8892= n

[Parent1]= i

[Parent2]= k

[Parent3]= m

Процесс d

[Server]= 8884= d

[Parent1]= a

[Child1]= 127.0.0.1= 8886= f

Процесс e

[Server]= 8885= e

[Parent1]= a

[Child1]= 127.0.0.1= 8890= k

[Child2]= 127.0.0.1= 8891= m

Процесс f

[Server]= 8886= f

[Parent1]= d

[Child1]= 127.0.0.1= 8890= k

[Child2]= 127.0.0.1= 8891= m

Процесс h

[Server]= 8888= h

[Parent1]= c

[Parent2]= b

[Child1]= 127.0.0.1= 8890= k

[Child2]= 127.0.0.1= 8891= m

Процесс g

[Server]= 8887= g

[Parent1]= b

[Parent2]= c

[Child1]= 127.0.0.1= 8890= k

[Child2]= 127.0.0.1= 8891= m

Процесс k

[Server]= 8890= k

[Parent1]= h

[Parent2]= g

[Parent3]= f

[Parent4]= e

[Child1]= 127.0.0.1= 8892= n

Процесс i

[Server]= 8889= i

[Parent1]= b

[Parent2]= c

[Child1]= 127.0.0.1= 8892= n

Процесс m

[Server]= 8891= m

[Parent1]= h

[Parent2]= g

[Parent3]= f

[Parent4]= e

[Child1]= 127.0.0.1

Port = 8892= n


2.3Результаты тестирования


Открываю порт 8883 для подключения родителей

Ожидаем запрос к подключению

родитель подключен...

Открываю порт 8889 для подключения родителей

Ожидаем запрос к подключению

родитель подключен...

ищем потомков...

подключаюсь к потомку c

Данные успешно отправлены!

выполняется процесс c

Процесс c выполнен

ищем потомков...

подключаюсь к потомку i

Данные успешно отправлены!

подключаюсь к потомку h

Данные успешно отправлены!

выполняется процесс i

выполняется процесс h

Проблема при открытие порта

Процесс i выполнен

Открываю порт 8889 для подключения родителей

Ожидаем запрос к подключению

Проблема при открытие порта

ищем потомков...

потомков нет.

Процесс h выполнен

Открываю порт 8888 для подключения родителей

Ожидаем запрос к подключению

Проблема при открытие порта

ищем потомков...

потомков нет.


Заключение


Благодаря использованию встроенных средств языка C# удалось создать проект, использующий сетевой стек и сетевые функции Windows. Что в конечном итоге сделало возможным создание программы, которая способна пересылать данные на удалённый компьютер. Следующим этапом стало создание удобного интерфейса. Интерфейс построен с использованием Windows Forms

В программе предусмотрен обмен как на локальном компьютере, так и при запуске на компьютерах с разными IP-адресами в пределах локальной или глобальной TCP/IP-сети. Предусмотрена возможность изменения IP-адреса компьютера при запуске процесса, посредством правки файла конфигурации.

Гибридный вариант реализации, когда часть процессов работает под управление ОС Linux, а оставшиеся - под ОС MS Windows не предусмотрена в силу ограничения работы .net framework на первом. Отладка производилась без применения виртуальных машин.


Список литературы


1.Гордеев А.В. Операционные системы СПб. Питер, 2004.

2.Рихтер Д.Ж. CLR via C#. Программирование на платформе.NET Framework 2.0 на языке С#. Мастер-класс. СПб. Питер, 2007

3.MSDN

Process (http://msdn.microsoft.com/ru-ru/library/system.diagnostics.process.aspx)(http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.beginreceive%28VS.80%29.aspx)

.Wikipedia

UDP (http://ru.wikipedia.org/wiki/UDP)/IP (http://ru.wikipedia.org/wiki/TCP/IP)

5.Форум stackoverflow.com


Курсовая работа по дисциплине: Операционные системы Распределенная синхронизация процессов

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ