Написание программы

Автор работы: Пользователь скрыл имя, 26 Декабря 2010 в 23:52, задача

Описание

На круглом столе находятся k тарелок с едой, между которыми лежит столько же вилок, k=4,…,7. В комнате имеется k философов, чередующих философские размышления с принятием пищи. За каждым философом закреплена своя тарелка; для еды философу нужны две вилки, причем он может использовать только вилки, примыкающие к его тарелке. Требуется так синхронизировать философов, чтобы каждый из них мог получить за ограниченное время доступ к своей тарелке. Предполагается, что длительности еды и размышлений философа конечны, но заранее недетерминированы (могут быть выбраны случайным образом из некоторого диапазона).

Содержание

1 Постановка задачи 3
2 Выводы 4
Приложение А Листинг программы 5
Приложение Б Пример протокола выполнения программы 13

Работа состоит из  1 файл

Отчет-ПП-2я.doc

— 130.50 Кб (Скачать документ)

      Содержание

 

        1 Постановка задачи  

      На круглом столе находятся k тарелок с едой, между которыми лежит столько же вилок, k=4,…,7. В комнате имеется k философов, чередующих философские размышления с принятием пищи. За каждым философом закреплена своя тарелка; для еды философу нужны две вилки, причем он может использовать только вилки, примыкающие к его тарелке. Требуется так синхронизировать философов, чтобы каждый из них мог получить за ограниченное время доступ к своей тарелке. Предполагается, что длительности еды и размышлений философа конечны, но заранее недетерминированы (могут быть выбраны случайным образом из некоторого диапазона).

      Синхронизацию философов (процессов) следует осуществить  средствами Win32. 
 
 
 

 

 2 Выводы 

      Результатом выполнения данной лабораторной работы стало разработанное нами приложение на языке C++ (Win32 API), выполняющее моделирование классической задачи «Обедающие философы».

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

      Необходимо  отметить, что в случае, если процессам недоступны определенные ресурсы (в данной задаче это вилки), они не переходят в активное ожидание, в отличие от процессов в первой лабораторной работе.

      Для синхронизации потоков в данной лабораторной задаче использованы критические секции. Вход в критическую секцию означает взятие вилки, а выход из критический секции – возвращение вилки.

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

      Кроме того, в разработанной программе  для одновременного «старта» порожденных  потоков реализован барьер (для его  реализации задействован механизм событий).

 

Приложение  А Листинг программы 

// PP2.cpp : Defines the entry point for the application.

// 

#include "stdafx.h"

#include "PP2.h"

#include "commctrl.h" 

#define MAX_LOADSTRING 100

#define ID_START  3300

#define EV_BARIER L"EV_BARIER" 

#define think_time 2000

#define eat_time 20000

#define wait_time 5000 

// Global Variables:

HINSTANCE hInst;        // current instance

TCHAR szTitle[MAX_LOADSTRING];     // The title bar text

TCHAR szWindowClass[MAX_LOADSTRING];   // the main window class name 

HFONT hFont;   // 

HWND hWnd;

HWND hEdCount,  //

            hButStart,  //

            hTable; 

HANDLE h_ev,   //хэндл события

            *h_thr;   //хэндлы нитей 

int* indexes=NULL;

int  count = 0;

bool started = false; 

int Y[5] = {0,0,0,0,0}; 
 

CRITICAL_SECTION *vilki; //указатель на массив вилок 

CRITICAL_SECTION main_sect; 

RECT rect; 

// Forward declarations of functions included in this code module:

ATOM    MyRegisterClass(HINSTANCE hInstance);

BOOL    InitInstance(HINSTANCE, int);

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM); 

DWORD WINAPI ThreadProc(LPVOID lpParameter)

{

      int id = *((int*)lpParameter);

      TCHAR id_str[5];

      _itow(id, id_str, 10);

      WaitForSingleObject(h_ev, INFINITE);

      srand( GetTickCount());

      int time=0;

      bool eated = false; 

      TCHAR str[200]=L""; 

      TCHAR str_time[200]=L"";

      TCHAR str_time1[200]=L"";

      SYSTEMTIME sys_time;

      SYSTEMTIME sys_time1; 

      while(1)

      { 

            time = (rand()*think_time)/RAND_MAX;

            GetLocalTime(&sys_time);

            Sleep(time); //думаем

            {

                  GetLocalTime(&sys_time1);

                  GetTimeFormat(LOCALE_SYSTEM_DEFAULT, NULL, &sys_time, L"HH':'mm':'ss':'ms", str_time, 200);

                  GetTimeFormat(LOCALE_SYSTEM_DEFAULT, NULL, &sys_time1, L"HH':'mm':'ss':'ms", str_time1, 200);

                  swprintf(str, L"(%s) Философ %s думает (%s ms)",str_time, id_str, str_time1); 

                  EnterCriticalSection(&main_sect);

                  SendMessage(hTable, LB_ADDSTRING, 0, (LPARAM)&str);

                  LeaveCriticalSection(&main_sect); 

            }

            eated = false; 

            while(!eated)

            {

                  if(TryEnterCriticalSection(&(vilki[id])) !=0 ) //пытаемся взять первую вилку

                  {

                        wcscpy(str,L"");

                        swprintf(str, L"Философ %s взял вилку %d", id_str, id); 

                        EnterCriticalSection(&main_sect);

                        SendMessage(hTable, LB_ADDSTRING, 0, (LPARAM)&str);

                        LeaveCriticalSection(&main_sect); 

                        if(id == count-1)//если это последний философ

                        {

                              if (TryEnterCriticalSection(&(vilki[0])) ==0 )  //если не удалось взять вторую вилку - кладем первую

                              {

                                    LeaveCriticalSection(&(vilki[id]) );

                                    swprintf(str, L"Философ %s положил вилку %d", id_str, id); 

                                    EnterCriticalSection(&main_sect);

                                    SendMessage(hTable, LB_ADDSTRING, 0, (LPARAM)&str);

                                    LeaveCriticalSection(&main_sect);

                              }

                              else

                              {

                                    swprintf(str, L"Философ %s взял вилку 0", id_str); 

                                    EnterCriticalSection(&main_sect);

                                    SendMessage(hTable, LB_ADDSTRING, 0, (LPARAM)&str);

                                    LeaveCriticalSection(&main_sect); 

                                    time = (rand()*eat_time)/RAND_MAX; 

                                    GetLocalTime(&sys_time);

                                    Y[id] = 10;

                                    InvalidateRect(hWnd, &rect, true);

                                    Sleep(time);//едим

                                    {

                                          GetLocalTime(&sys_time1);

                                          Y[id] = 0;

                                          InvalidateRect(hWnd, &rect, true);

                                          GetTimeFormat(LOCALE_SYSTEM_DEFAULT, NULL, &sys_time, L"HH':'mm':'ss':'ms", str_time, 200);

                                          GetTimeFormat(LOCALE_SYSTEM_DEFAULT, NULL, &sys_time1, L"HH':'mm':'ss':'ms", str_time1, 200);

                                          swprintf(str, L"(%s) Философ %s кушает (%s ms)",str_time, id_str, str_time1); 

                                          EnterCriticalSection(&main_sect);

                                          SendMessage(hTable, LB_ADDSTRING, 0, (LPARAM)&str);

                                          LeaveCriticalSection(&main_sect); 

                                          eated = true; 

                                    }

                                    LeaveCriticalSection(&(vilki[id]) );  //кладем обе вилки

                                    swprintf(str, L"Философ %s положил вилку %d", id_str, id); 

                                    EnterCriticalSection(&main_sect);

                                    SendMessage(hTable, LB_ADDSTRING, 0, (LPARAM)&str);

                                    LeaveCriticalSection(&main_sect); 

                                    LeaveCriticalSection(&(vilki[0]) );

                                    swprintf(str, L"Философ %s положил вилку 0", id_str); 

                                    EnterCriticalSection(&main_sect);

                                    SendMessage(hTable, LB_ADDSTRING, 0, (LPARAM)&str);

                                    LeaveCriticalSection(&main_sect);

                              }

Информация о работе Написание программы