Средства синхронизации и взаимодействия процессов



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

Пренебрежение вопросами синхронизации процессов, выполняю-щихся в режиме мультипрограммирования, может привести к их неправильной работе или даже к сбою работы ОС. Рассмотрим, например, программу печати заданий (рис. 2.2). Эта программа печатает по очереди все задания, имена которых последовательно в порядке поступления записываются в очередь заданий. Особая переменная N, также доступная всем процессам-клиентам, содержит номер первой свободной позиции для задания в очереди. Процессы-клиенты читают эту переменную, записывают в соответствующую позицию очереди имя своего задания и наращивают значение N на единицу. Предположим, что в некоторый момент процесс A решил распечатать свой файл, для этого он прочитал значение переменной N, значение которой для определен-ности предположим равным 4. Процесс запомнил это значение, но поместить задание не успел, так как его выполнение было прервано (например, вследствие исчерпания кванта). Очередной процесс B, желающий послать задание на печать, прочитал то же самое значение переменной N, поместил в четвертую позицию свое задание и нарастил значение переменной на единицу.

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

Таким образом, процесс A никогда не увидит свое задание распечатанным. Сложность проблемы синхронизации состоит в нерегулярности возникающих ситуаций. В предыдущем примере можно представить и другое развитие событий: были потеряны задания

 

 

Рис. 2.2. Пример необходимости синхронизации

 

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

Контрольный пример

Необходимо разработать программу, осуществляющую моделирова-ние режима работы с разделением времени между независимыми процессами.

 

/* ЛИСТИНГ ПРОГРАММЫ */

 

#include <stdio.h>

#include <conio.h>

#include <bios.h>

#include <dos.h>

 

#define ESC 27

#define INS 82

#define DEL 83

 

#define dX 14           //ширина окна процесса

#define dY 4            //высота окна процесса

#define ID_COUNT 20 //количество процессов

#define TIME 0.01       //время выполнения процесса

#define DELAY –6000 //задержка в тыс.операций для отключ.

 

/*               массив координат окон для процессов           */

int xy[2][ID_COUNT]={{01,01,01,01,17,17,17,17,33,33,33,33,49,49,49,49,65,65,65,65},{01,07,13,19,01,07,13,19,01,07,13,19,01,07,13,19,01,07,13,19}};

/* массив статуса процессов: 0 – свободен, 1 – на выполнении */

int ID[ID_COUNT]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

 

typedef unsigned char BYTE ;

/*                               прототипы функций                     */

void ShowMenu();     //главное меню

void ShowCursor();   //показать курсор

void HideCursor();   //спрятать курсор

/*                           описание класса процесса                  */

class TProcess

 {

       int id;          //номер процесса

       BYTE x,y;         //координаты окна процесса

public:

       long CountOperations; //кол-во операций процесса

       TProcess *next; //указатель на следующий процесс

       TProcess *prev; //указатель на предыд. процесс

       int GetID();     //получить номер процесса

       long GetTime(); //получить кол-во невыполн.операц.

       void GetParams(); //задать параметры процесса

       void ShowWND(); //показать окно процесса

       void HideWND(); //спрятать окно процесса

       void ActiveWND(); //активизировать окно процесса

       int Time();      //выполнение процесса

 };

/*метод получения количества невыполненных операций*/

long TProcess::GetTime()

{

return CountOperations;

}

/*метод выполнения процесса в течении кванта времени*/

int TProcess::Time()

{

double th1,th2;

struct time t;

ActiveWND();

gettime(&t);

th1=t.ti_hour*60*60+t.ti_min*60+t.ti_sec+(double)(t.ti_hund)/100;

do

{

th2=0;

gettime(&t);

gotoxy(2,2);

if (CountOperations<0)

       cprintf("Complete...     ");

else

{

  cprintf("%2d:%02d:%02d.%02d",t.ti_hour, t.ti_min, t.ti_sec, t.ti_hund);

  cprintf(" %8ld",CountOperations);

}

th2=t.ti_hour*60*60+t.ti_min*60+t.ti_sec+(double)(t.ti_hund)/100;

–CountOperations;

}

while(th2<=th1+TIME);

return 0;

}

/*метод активизации окна выполнения процесса*/

void TProcess::ActiveWND()

{

textcolor(14);

textbackground(1);

window(x+1,y+1,x+dX–1,y+dY–1);

}

/*метод удаления окна выполнения процесса с экрана*/

void TProcess::HideWND()

{

textcolor(15);

textbackground(0);

window(x,y,x+dX,y+dY);

clrscr();

}

/*метод вывода окна выполнения процесса на экран*/

void TProcess::ShowWND()

{

textcolor(15);

textbackground(1);

window(x,y,x+dX,y+dY);

clrscr();

window(x,y,x+dX,y+dY+1);

cprintf("┌[Process #%2d]┐",id);

cprintf("│        │");

cprintf("│        │");

cprintf("│        │");

cprintf("└─────────────┘");

ActiveWND();

}

/*метод получения номера текущего процесса*/

int TProcess::GetID()

{ return id;}

/*метод создания нового процесса*/

void TProcess::GetParams()

{

ShowCursor();

for(int i=0;i<ID_COUNT;i++)

if (!ID[i]) break;

ID[i]=1;

id=i;

textcolor(15);

textbackground(0);

window(1,24,80,24);

clrscr();

cprintf("Создание нового процесса # %d.",id);

cprintf(" Количество операций (в тысячах) = ");

if (!cscanf("%ld",&CountOperations)) CountOperations=DELAY–1000;

CountOperations*=1000;

x=xy[0][id];

y=xy[1][id];

prev=NULL;

next=NULL;

HideCursor();

}

/*прототип функции задания процесса для удаления */

TProcess * GetDelProcess(TProcess *);

/*прототип функции очистки командеой строки*/

void ClearCommandLine();

int main(void)

{

int key, count;

long d;

class TProcess * ptr1=NULL;

class TProcess * ptr2=NULL;

class TProcess * BPtr=NULL; //указатель на начало списка процессов

class TProcess * EPtr=NULL; //указатель на конец списка процессов

HideCursor();

textcolor(15);

clrscr();

ShowMenu();

do

{

/* обработка процессов,пока не нажата любая клавиша */

ptr1=BPtr;

do

{

       if (!BPtr) continue;

       ptr1=ptr1–>next;

       ptr1–>Time();

       d=ptr1–>GetTime();

       if (d<DELAY)

       {

       ptr1–>prev–>next=ptr1–>next;

       ptr1–>next–>prev=ptr1–>prev;

       if (ptr1==BPtr) BPtr=ptr1–>next;

       if (ptr1==EPtr) EPtr=ptr1–>prev;

       if (ptr1==BPtr&&ptr1==EPtr) EPtr=BPtr=NULL;

       ptr1–>HideWND();

       ID[ptr1–>GetID()]=0;

       delete ptr1;

       }

}                   // ожидание нажатия клавиши

while (!_bios_keybrd(_KEYBRD_READY)) ;

/*               обработка нажатия клавиши                */

key = getch();

if (!key) key = getch();

switch(key)

{

       case INS:           //создание нового процесса

        for(int i=0,count=0;i<ID_COUNT;i++)

       if (!ID[i]) {count=1;break;}

        if (!count)

        {

       ClearCommandLine();

       cprintf("\n\nНевозможно создать новый процесс.Уже создано 20 процессов.");

       break;

        }

        ptr2 = EPtr;

        ptr1 = NULL;

        ptr1 = new TProcess;

        if (!ptr1)

        {

       ClearCommandLine();

       cprintf("\n\nОшибка выделения памяти для нового процесса.");

       break;

        }

        if (!BPtr) BPtr=ptr1;

        EPtr=ptr1;

        ptr1–>GetParams();

        ptr1–>prev=ptr2;

        ptr2–>next=ptr1;

        BPtr–>prev=EPtr;

        EPtr–>next=BPtr;

        ptr1–>ShowWND();

        ClearCommandLine();

        break;

       case DEL:          //удаление процесса

        ptr1=GetDelProcess(BPtr);

        if (ptr1)

        {

       ptr1–>prev–>next=ptr1–>next;

       ptr1–>next–>prev=ptr1–>prev;

       if (ptr1==BPtr) BPtr=ptr1–>next;

       if (ptr1==EPtr) EPtr=ptr1–>prev;

       if (ptr1==BPtr&&ptr1==EPtr) EPtr=BPtr=NULL;

       ptr1–>HideWND();

       ID[ptr1–>GetID()]=0;

       delete ptr1;

       ClearCommandLine();

        }

        break;

}

}

while(key!=ESC);                  //выход по нажатию Esc

//удаление всех процессов

ptr1=BPtr;

do

{

if (!ptr1) break;

delete ptr1;

ptr1=ptr1–>next;

}

while(ptr1!=BPtr);

 

textcolor(15);

textbackground(0);

window(1,1,80,25);

clrscr();

return 0;

}

void ClearCommandLine()

{

textcolor(15);

textbackground(0);

window(1,24,80,24);

clrscr();

}

/*функция получения номера процесса для удаления*/

TProcess * GetDelProcess(TProcess * BPtr)

{ int id;

TProcess *ptr, *ptrf=NULL;

ClearCommandLine();

ShowCursor();

cprintf("Введите номер процесса для удаления : ");

cscanf("%d",&id);

HideCursor();

ptr=BPtr;

do

{ if (!ptr) break;

if (ptr–>GetID()==id)

{

ptrf=ptr;

break;

}

ptr=ptr–>next;

}

while(ptr!=BPtr);

if (!ptrf)

{

clrscr();

cprintf("Ощибка. Процесс #%d не найден.",id);

//if (!getch()) getch();

}

return ptrf;

}

 

/*вывод рабочего меню на экран*/

void ShowMenu()

{

 textbackground(7);

 window(1,25,80,25);

 clrscr();

 textcolor(4); cprintf(" INS");

 textcolor(0); cprintf(" – создать новый процесс ");

 textcolor(4); cprintf(" DEL");

 textcolor(0); cprintf(" – удалить процесс ");

 textcolor(4); cprintf(" ESC");

 textcolor(0); cprintf(" – выход из программы ");

}

/*функция гашения курсора*/

void ShowCursor()

{

asm{

mov ah,1

mov bh,0

mov cx,0606h

int 10h

}

}

/*функция восстановления курсора*/

void HideCursor()

{

asm{

mov ah,1

mov bh,0

mov cx,2000h

int 10h

}

}

 

Разработанная программа позволяет пользователю создавать до двадцати выполняемых процессов (количество процессов ограничено в связи с использованием текстового режима 80*25 и невозможностью вместить большое число выполняемых процессов).

Программа реализована на языке Си и одинаково корректно работает в DOS и в DOS-сессии Windows [6].

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

Моделирование режима разделения времени заключается в том, что каждый процесс работает в течение короткого промежутка времени, затем управление передается следующему из списка процессу. Под работой процесса понимается вывод на экран в окне рабочего процесса значения текущего времени и текущего количества операций для выполнения.

Если процесс выполнил требуемое количество операций, то на эк-ране возникает надпись о его завершении «Complete …» и через малый промежуток времени окно процесса исчезает с экрана (рис. 2.4 и 2.5). При этом сам процесс удаляется из списка заданий. Для удаления процесса в произвольный момент времени необходимо нажать клавишу DEL и в строке запроса ввести номер процесса для удаления. Если процесс с указанным номером будет найден, то он исчезнет с экрана и удалится из списка обрабатываемых процессов (рис. 2.6). Для выхода из программы необходимо воспользоваться клавишей ESC. После этого все процессы удаляются, и осуществляется завершение работы программы.

 

 

 

Рис. 2.3. Создание нового процесса

 

 

Рис. 2.4. Работа и завершение процессов

 

 

 

Рис. 2.5. Активные и завершенные процессы

 

 

 

Рис. 2.6. Запрос на удаление процесса

Лабораторная работа № 2

Цель работы: разработать программу, осуществляющую моделирование режима работы с разделение времени.

Результат:  отчет о лабораторной работе и программа, моделирующая режим работы с разделением времени.

 

Список вариантов

 

Вариант 1 Создание хаотичного режима передачи сообщений. Каждый процесс может отправлять сообщение любому из своих соседей и самому себе. Случайный способ выбора следующего
Вариант 2 Одновременная работа нескольких внешних программ под управлением менеджера. Пользователь может запускать, закрывать, приостанавливать любой активный процесс
Вариант 3 Одновременный опрос выбранных портов ПК. Синхронизация в режиме реального времени
Вариант 4 Параллельная сортировка массивов. Передача управления осуществляется после перестановки значений. Первым завершается процесс, с меньшим количеством перестановок
Вариант 5 Одновременный расчет результатов нескольких математических уравнений. При решении используются общие области оперативной памяти (переменные)
Вариант 6 Вывод нескольких графических объектов. Скорость вращения объектов зависит от приоритета. Приоритет и положение объекта на экране должны задаваться пользователем
Вариант 7 Работа с двумя и более одновременными независимыми операциями умножения матриц. Пользователь должен менять приоритет процессов во время работы
Вариант 8 Работа нескольких параллельных процессов с одной внешней базой. Приоритет и ключи поиска у разных процессов – различны. База доступна только для чтения
Вариант 9 Одновременный отсчет. Синхронизация по таймеру. От величины приоритета зависит уменьшение числа в течение одного интервала
Вариант 10 Генерация нескольких движущихся объектов в пределах одного окна. При движении необходимо учитывать операции столкновения и отражения управляемых объектов

3. РАБОТА С РАЗДЕЛЕННЫМИ ФАЙЛАМИ
НА УРОВНЕ ПРОЦЕССОВ

Важным понятием синхронизации процессов является понятие «критическая секция» программы. Критическая секция – это часть программы, в которой осуществляется доступ к разделяемым данным. Чтобы исключить эффект гонок по отношению к некоторому ресурсу, необходимо обеспечить, чтобы в каждый момент в критической секции, связанной с этим ресурсом, находился максимум один процесс. Этот прием называют взаимным исключением [12].

Системы, состоящие из нескольких процессов, часто легче программировать, используя так называемые критические секции. Когда процессу нужно читать или модифицировать некоторые разделяемые структуры данных, он прежде всего входит в критическую секцию для того, чтобы обеспечить себе исключительное право использования этих данных. При этом он уверен, что никакой процесс не будет иметь доступа к этому ресурсу одновременно с ним. Это называется взаимным исключением. В однопроцессорных системах критические секции защищаются семафорами, мониторами и другими аналогичными конструкциями. Рассмотрим, какие алгоритмы могут быть использованы в распределенных системах.

Наиболее очевидный и простой путь реализации взаимного исключения в распределенных системах – это применение тех же методов, которые используются в однопроцессорных системах. Один из процессов выбирается в качестве координатора (например, процесс, выполняющийся на машине, имеющей наибольшее значение сетевого адреса). Когда какой-либо процесс хочет войти в критическую секцию, он посылает сообщение с запросом к координатору, оповещая его о том, в какую критическую секцию он хочет войти, и ждет от координатора разрешение. Если в этот момент ни один из процессов не находится в критической секции, то координатор посылает ответ с разрешением. Если же некоторый процесс уже выполняет критическую секцию, связанную с данным ресурсом, то никакой ответ не посылается. Запрашивавший процесс ставится в очередь, и после освобождения критической секции ему отправляется ответ-разрешение. Этот алгоритм гарантирует взаимное исключение одновременного доступа в критическую секцию, но вследствие своей централизованной природы обладает низкой отказоустойчивостью.

Когда процесс хочет войти в критическую секцию, он формирует сообщение, содержащее имя нужной ему критической секции, номер процесса и текущее значение времени. Затем он посылает это сообщение всем другим процессам. Предполагается, что передача сообщения надежна, то есть получение каждого сообщения сопровождается подтверждением. Когда процесс получает сообщение такого рода, его действия зависят от того, в каком состоянии по отношению к указанной в сообщении критической секции он находится. Имеют место три ситуации:

1. Если получатель не находится и не собирается входить в критическую секцию в данный момент, то он отсылает назад процессу-отправителю сообщение с разрешением.

2. Если получатель уже находится в критической секции, то он не отправляет никакого ответа, а ставит запрос в очередь.

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

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

Контрольный пример

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

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

При запуске программы происходит автоматическое создание текстового файла «RichEdit.txt», в который помещается общая для всех процессов информация для вывода. Далее при создании каждого нового процесса к данному файлу будет осуществляться обращение.

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

 

/* ЛИСТИНГ ПРОГРАММЫ */

 

//Модуль окна-процесса

unit DocumentForm;

 

interface

 

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls, ComCtrls, ToolWin, Menus, ExtActns, StdActns, ActnList,

ImgList;

 

type

TFDoc = class(TForm)

RichEdit: TRichEdit;

ToolBar1: TToolBar;

ToolButton1: TToolButton;

  ToolButton2: TToolButton;

ToolButton3: TToolButton;

ActionList1: TActionList;

EditCut1: TEditCut;

EditCopy1: TEditCopy;

EditPaste1: TEditPaste;

EditUndo1: TEditUndo;

EditDelete1: TEditDelete;

RichEditBold1: TRichEditBold;

RichEditItalic1: TRichEditItalic;

RichEditUnderline1: TRichEditUnderline;

RichEditBullets1: TRichEditBullets;

RichEditAlignLeft1: TRichEditAlignLeft;

RichEditAlignRight1: TRichEditAlignRight;

RichEditAlignCenter1: TRichEditAlignCenter;

ToolButton4: TToolButton;

ToolButton6: TToolButton;

EditDelete2: TEditDelete;

ImageList1: TImageList;

ToolButton5: TToolButton;

ToolButton7: TToolButton;

ToolButton8: TToolButton;

ToolButton9: TToolButton;

ToolButton10: TToolButton;

ToolButton11: TToolButton;

ToolButton12: TToolButton;

ToolButton13: TToolButton;

procedure FormClose(Sender: TObject; var Action: TCloseAction);

procedure FormShow(Sender: TObject);

private

{ Private declarations }

public

procedure FrameFill;

{ Public declarations }

end;

 

var

FDoc: TFDoc;

implementation

uses MainForm;

{$R *.dfm}

procedure TFDoc.FrameFill;

begin

CloseFile(FMain.FText);

FMain.Frame11.Memo1.Lines.LoadFromFile('out.txt');

Append(FMain.FText);

end;

 

procedure TFDoc.FormClose(Sender: TObject; var Action: TCloseAction);

begin

Action := caFree;

FMain.StatusBar1.Panels[0].Text:='Запись содержимого процесса "'+

                              Caption+'" в файл out.txt';

Writeln(FMain.FText,RichEdit.Lines.Text);

FrameFill;

if FMain.MDIChildCount=1 then

CloseFile(FMain.FText);

end;

 

procedure TFDoc.FormShow(Sender: TObject);

const

Colors: array[0..6] of TColor = (clWhite, clBlue, clGreen, clRed, clTeal,

                              clPurple, clLime);

var str:string;

begin

Height:=165;

Width:=280;

if FMain.MDIChildCount=1 then

begin

AssignFile(FMain.FText, 'out.txt'); { File selected in dialog }

Rewrite(FMain.FText);

end;

Reset(FMain.RichText);

RichEdit.Color:=Colors[FMain.MDIChildCount mod 7];

FMain.StatusBar1.Font.Color:=RichEdit.Color;

RichEdit.Lines.Add('            Процесс № '+IntToStr(FMain.MDIChildCount));

FMain.StatusBar1.Panels[0].Text:='Чтение содержания процесса "'+

                              Caption+IntToStr(FMain.MDIChildCount)+'" из файла RichEdit.txt';

 while not eof(FMain.RichText) do

begin

Readln(FMain.RichText, str);

RichEdit.Lines.Add(str);

end;

end;

end.

//Модуль управления процессами

unit MainForm;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, ComCtrls, ToolWin, Menus, ImgList, ActnList, StdActns, ExtActns,

Unit1;

type

TFMain = class(TForm)

MenuProcess: TMainMenu;

MFile: TMenuItem;

StatusBar1: TStatusBar;

MHelp: TMenuItem;

MExit: TMenuItem;

ActionList1: TActionList;

MCreate: TMenuItem;

About1: TMenuItem;

RichEditBold1: TRichEditBold;

RichEditBullets1: TRichEditBullets;

FileSaveAs1: TFileSaveAs;

FileSaveAs2: TFileSaveAs;

ImageList2: TImageList;

WindowCascade1: TWindowCascade;

WindowTileHorizontal1: TWindowTileHorizontal;

WindowTileVertical1: TWindowTileVertical;

WindowClose1: TWindowClose;

N1: TMenuItem;

N2: TMenuItem;

Cascade1: TMenuItem;

ileHorizontally1: TMenuItem;

ileVertically1: TMenuItem;

Frame11: TFrame1;

procedure MExitClick(Sender: TObject);

procedure MCreateClick(Sender: TObject);

procedure FormShow(Sender: TObject);

procedure About1Click(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure FormClose(Sender: TObject; var Action: TCloseAction);

private

{ Private declarations }

public

FText: Text;

RichText: Text;

procedure CreateDocument(const Name: string);

{ Public declarations }

end;

 

var

FMain: TFMain;

implementation

uses DocumentForm, AboutForm;

{$R *.dfm}

procedure TFMain.CreateDocument(const Name: string);

var

Doc: TFDoc;

begin

Doc := TFDoc.Create(Application);

Doc.Caption := Name;

end;

 

procedure TFMain.MExitClick(Sender: TObject);

begin

Close;

end;

 

procedure TFMain.MCreateClick(Sender: TObject);

begin

CreateDocument('Процесс ' + IntToStr(MDIChildCount + 1));

end;

 

procedure TFMain.FormShow(Sender: TObject);

begin

FDoc.Close;

FDoc.Free;

Frame11.Memo1.Clear;

StatusBar1.Panels[0].Text:='';

end;

 

procedure TFMain.About1Click(Sender: TObject);

begin

FAbout.ShowModal;

end;

 

procedure TFMain.FormCreate(Sender: TObject);

begin

AssignFile(RichText, 'RichEdit.txt'); { File selected in dialog }

Rewrite(RichText);

Writeln(RichText,' Данное окно являестя новым');

Writeln(RichText,'процессом,который не зависит от');

Writeln(RichText,'остальных открытых процессов.');

CloseFile(RichText);

end;

 

procedure TFMain.FormClose(Sender: TObject; var Action: TCloseAction);

begin

 try

CloseFile(RichText);

 except

 end;

end;

end.

 

Создание нового процесса осуществляется при помощи горизонтального меню «Процесс», в котором необходимо выбрать подпункт «Создать новый …» (рис. 3.1 и 3.2). Выход из программы осуществляется соответствующим подпунктом меню. Кроме того, в пункте меню «Окна» можно задать режим вывода окон (процессов) на экране: горизонтальное размещение «Tile Horizontally», вертикальное размещение «Tile Vertically», каскадное размещение «Cascade» или закрыть текущее окно-процесс. При закрытии окна-процесса в конец файла «Out.txt» записывается содержимое закрываемого процесса. При этом в правой части главного окна показывается содержимое этого файла (рис. 3.3).

 

 

Рис. 3.1. Главное окно-меню программы

 

 

 

Рис. 3.2. Перечень созданных процессов

 

 

 

Рис. 3.3. Отображение в фрейме окна записи процессов в разделяемый файл

 

Лабораторная работа № 3

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

Результат:  отчет о лабораторной работе и программа, в которой процессы борются за обладание ресурсом (файлом).

 

Список вариантов

 


Дата добавления: 2018-04-15; просмотров: 683; Мы поможем в написании вашей работы!






Мы поможем в написании ваших работ!