Помощничек
Главная | Обратная связь


Археология
Архитектура
Астрономия
Аудит
Биология
Ботаника
Бухгалтерский учёт
Войное дело
Генетика
География
Геология
Дизайн
Искусство
История
Кино
Кулинария
Культура
Литература
Математика
Медицина
Металлургия
Мифология
Музыка
Психология
Религия
Спорт
Строительство
Техника
Транспорт
Туризм
Усадьба
Физика
Фотография
Химия
Экология
Электричество
Электроника
Энергетика

Листинг процедур, обеспечивающих решение задачи



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

Листинг программы-клиента.

#include <vcl.h>

#pragma hdrstop

#include "Unit1.h"

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

LPTSTR myPipe = "\\\\.\\pipe\\mynamedpipe";

HANDLE hPipe;

int Number;

const char msg[6][50] = {"left the dinning room", "finished to eat", "is eating now", "wants to eat", "is thinking", "came to the table"};

void SendMsg(int message_num)

{

DWORD cbWritten;

int Buffer[2] = {Number, message_num};

WriteFile(hPipe, &Buffer, sizeof(Buffer), &cbWritten, NULL);

}

void start()

{

Form1->Memo1->Clear();

int N = atoi(ParamStr(1).c_str()); // количество философов

Number = atoi(ParamStr(2).c_str()); // номер данного философа

Form1->Caption="Philosopher "+IntToStr(Number);

while (1)

{

hPipe = CreateFile (myPipe,

GENERIC_READ |

GENERIC_WRITE,

FILE_SHARE_READ,

NULL,

OPEN_EXISTING,

0,

NULL);

if (hPipe != INVALID_HANDLE_VALUE) break;

}

for(;;)

{

Form1->Memo1->Lines->Add("Philosopher "+ IntToStr(Number)+" "+msg[5]);

SendMsg(5); // философ подходит к столу

Sleep(random(2001)+3000);

HANDLE myMutex,myCritical;

// номер левого (правого) соседа философа

int LeftNeighbour=(Number + N -1)%N,

RightNeighbour=(Number+1)%N;

AnsiString LeftFork=IntToStr(LeftNeighbour),

RightFork=IntToStr(RightNeighbour),

eat=IntToStr(Number),

Crit="myCritical";

// создаётся мьютекс взаимного исключения входа в критическую оласть

myCritical = CreateMutex(NULL, false, Crit.c_str());

Form1->Memo1->Lines->Add("Philosopher "+ IntToStr(Number)+" "+msg[4]);

SendMsg(4); // философ размышляет

Sleep(random(2001)+3000);

Form1->Memo1->Lines->Add("Philosopher "+ IntToStr(Number)+" "+msg[3]);

SendMsg(3); // философ хочет есть

bool flag=false;

while (!flag)

{

// ожидание входа в критическую область

WaitForSingleObject(myCritical, INFINITE);

HANDLE LeftForkUsed,RightForkUsed;

// проверка состояния левого и правого соседей

LeftForkUsed = OpenMutex(MUTEX_ALL_ACCESS, 0, LeftFork.c_str());

RightForkUsed = OpenMutex(MUTEX_ALL_ACCESS, 0, RightFork.c_str());

if (!LeftForkUsed&&!RightForkUsed) // если соседи не едят

{

flag=true;

myMutex = CreateMutex(NULL, false, eat.c_str());

SendMsg(2); // философ приступает к приёму пищи

Form1->Memo1->Lines->Add("Philosopher "+ IntToStr(Number)+" "+msg[2]);

ReleaseMutex(myCritical); // выход из критической области

}

else

{

ReleaseMutex(myCritical);

CloseHandle(LeftForkUsed);

CloseHandle(RightForkUsed);

}

}

Sleep(random(2001)+3000);

SendMsg(1); // прекращение приёма пищи

Form1->Memo1->Lines->Add("Philosopher "+ IntToStr(Number)+" "+msg[1]);

Form1->Memo1->Lines->Add("Philosopher "+ IntToStr(Number)+" "+msg[0]);

SendMsg(0); //философ покидает столовую

CloseHandle(myMutex);

Sleep(random(2001)+3000);

}

}

void __fastcall TForm1::FormShow(TObject *Sender)

{

CreateThread(0, 0, (LPTHREAD_START_ROUTINE) start,0, 0, 0);

}

Листинг программы-сервера.

#include <vcl.h>

#include <stdio.h>

#pragma hdrstop

 

#include "Unit1.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

LPTSTR myPipe = "\\\\.\\pipe\\mynamedpipe";

int Count = 5;

int bSize = 255, MaxWaitTime = 0;

const char msg[6][50] = {"left the dinning room", "finished to eat", "is eating now", "wants to eat", "is thinking", "came to the table"};

 

VOID InstanceThread(LPVOID lpvParam)

{

DWORD cbBytesRead;

BOOL ReadSuc;

HANDLE hPipe = (HANDLE) lpvParam;

int Buffer[2];

while (1)

{

//Считывание запросов клиента из канала

ReadSuc = ReadFile(

hPipe, // дескриптор канала

Buffer, // выходной буфер

sizeof(Buffer), // размер буфера

&cbBytesRead, // сколько байт считывать

NULL); // синхронный ввод/вывод

Form1->Memo1->Lines->Add("Philosopher "+ IntToStr(Buffer[0])+" "+msg[Buffer[1]]);

if (! ReadSuc || cbBytesRead == 0)

break;

}

 

FlushFileBuffers(hPipe);//сброс содержимого канала

DisconnectNamedPipe(hPipe);//разъединение

CloseHandle(hPipe);//закрытие дескриптора канала

}

 

void start()

{ Form1->Memo1->Clear();

char PARAMS[100];

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

{

sprintf(PARAMS, "%d %d", Count, i + 1);

ShellExecute(0, NULL, "Client.exe", PARAMS, NULL, SW_SHOW);

}

DWORD Identifier;

HANDLE hThread, hPipe;

BOOL ConnectSuc;

while (1)

{

hPipe = CreateNamedPipe(

myPipe, // имя канала

PIPE_ACCESS_DUPLEX, // доступ на

//чтение/запись

PIPE_TYPE_MESSAGE | // канал передачи

// сообщений

PIPE_READMODE_MESSAGE | // режим чтения

// сообщений

PIPE_WAIT, // блокирующийся режим

PIPE_UNLIMITED_INSTANCES, // максимальное число

// экземпляров этого канала в системе

bSize, // размер выходного буфера

bSize, // размер входного буфера

MaxWaitTime, // таймаут для клиента

NULL); // атрибуты

//безопасности отсутствуют

ConnectSuc = ConnectNamedPipe(hPipe, NULL) ?

TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);

if (ConnectSuc)

{

hThread = CreateThread(

NULL, // Отсутствие атрибутов безопасности

0, // размер стека потока выбрать по умолчанию

(LPTHREAD_START_ROUTINE) InstanceThread,

(LPVOID) hPipe, // параметр потока

0, // не приостановленный

&Identifier); // возврат идентификатора потока

CloseHandle(hThread);

}

else

CloseHandle(hPipe);

}

}

void __fastcall TForm1::Button1Click(TObject *Sender)

{

 

CreateThread(0, 0, (LPTHREAD_START_ROUTINE) start,0, 0, 0);

}

Результат работы программы представлен на рисунке 2.

Рисунок 2 – Результат работы программы

Вывод

Таким образом, была решена задача об обедающих философах. Представленная программа предотвращает тупиковую ситуацию, когда ни один из философов не может начать есть, и обеспечивает корректное поведение философов. Программа была составлена средствами Borland Developer Studio 2006 Turbo C++.


 




Поиск по сайту:

©2015-2020 studopedya.ru Все права принадлежат авторам размещенных материалов.