Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Потоки и их синхронизация, Задача «обедающие философы» 
:(
    Опции темы
Pakshin A. S.
  Дата 20.3.2007, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 1
Всего: 61



Вот есть такая задачка:
Цитата

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


В прикрепленном файле лежит решение задачи.

Но вот только программа работает не корректно:
1) не отображаются вилки, которые должны быть только в правой руке, т. е. философ взял вилку в правую и ждет в левую...
2) почему-то дает кушать только двум философам в основном: например, первому и пятому...

 smile 

В чем проблемы?

Присоединённый файл ( Кол-во скачиваний: 60 )
Присоединённый файл  Philosophers.rar 8,14 Kb
PM   Вверх
ama_kid
Дата 20.3.2007, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 9
Всего: 95



Pakshin A. S.
Блин, спасибо тебе за такую интересную задачу....  smile
У тебя мьютекс не захватывался при захвате вилки, поэтому все философы набрасываются на первые две. Кроме того, при создании мьютексов (в инициализации) ты создавал один, другие четыре - впустую, ибо одинаковые имена у мьютексов не могут быть...
Вот я подправил код, у меня вроде работает...
Код

unit U_Restaurant;

interface

uses
  Classes, Windows, StdCtrls, SysUtils;

type
  TPhilosoph = class(TThread)
  public
    id: integer;
    FLabels: array [1..5] of TLabel;
  private
    i, j: integer;
    procedure SetForksR;
    procedure SetForksL;
    procedure FreeForks;
  protected
    procedure Execute; override;
  end;

var
  _Philosophiers: array [1..5] of TPhilosoph;

procedure InitializeRestaurant;

implementation

var
  CanEat: THandle;
  Forks: array [1..5] of THandle;

procedure TPhilosoph.SetForksR;
begin
  FLabels[i].Caption:=IntToStr(id);
  OpenMutex(MUTEX_ALL_ACCESS,false,PAnsiChar('Вилка '+IntToStr(i)));
end;

procedure TPhilosoph.SetForksL;
begin
  FLabels[j].Caption:=IntToStr(id);
  OpenMutex(MUTEX_ALL_ACCESS,false,PAnsiChar('Вилка '+IntToStr(j)));
end;

procedure TPhilosoph.FreeForks;
begin
  FLabels[i].Caption:='0';
  FLabels[j].Caption:='0'
end;

procedure TPhilosoph.Execute;
var
  find: boolean;
begin
  while not Terminated do
    begin
      if WaitForSingleObject(CanEat, INFINITE) = WAIT_OBJECT_0 then
        begin
          (* Ищем вилку в правую руку *)
          i:=1;
          find:=false;
          while not find do
            begin
              if WaitForSingleObject(Forks[i], 0) = WAIT_OBJECT_0 then
                begin
                  Synchronize(SetForksR);
                  find:=true
                end
              else
                begin
                  inc(i);
                  if i >= 6 then
                    i:=1
                end
            end;
          (* Ждем вилку в левую руку *)
          j:=i + 1;
          if j >= 6 then
            j:=1;
          if WaitForSingleObject(Forks[j], INFINITE) = WAIT_OBJECT_0 then
            begin
              Synchronize(SetForksL);
              Sleep(3000); // кушаем
              Synchronize(FreeForks)
            end;
          ReleaseMutex(Forks[j]);
          ReleaseMutex(Forks[i])
        end;
      ReleaseSemaphore(CanEat, 1, nil)
    end
end;

procedure InitializeRestaurant;
var
  i: integer;
begin
  CanEat:=CreateSemaphore(nil, 4, 4, 'Философы у стола');
  for i:=1 to 5 do
    Forks[i]:=CreateMutex(nil, false, PAnsiChar('Вилка '+IntToStr(i)));
end;

end.



--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
Pakshin A. S.
Дата 20.3.2007, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 1
Всего: 61



Цитата(ama_kid @  20.3.2007,  20:52 Найти цитируемый пост)
У тебя мьютекс не захватывался при захвате вилки, поэтому все философы набрасываются на первые две. Кроме того, при создании мьютексов (в инициализации) ты создавал один, другие четыре - впустую, ибо одинаковые имена у мьютексов не могут быть...

А нам не рассказывали про это!
Спасибо! Сейчас побегу пробовать...

Добавлено @ 21:44 
А OpenSemaphore() не нужно выполнять?
PM   Вверх
Yanis
Дата 20.3.2007, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2937
Регистрация: 9.2.2004
Где: Москва

Репутация: 6
Всего: 111



smile
Pakshin A. S., Только по моему не обедающие, а голодные философы smile


--------------------
user posted image *щёлк*
PM MAIL WWW ICQ   Вверх
Pakshin A. S.
Дата 20.3.2007, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 5056
Регистрация: 16.2.2003

Репутация: 1
Всего: 61



 smile 

Цитата(Yanis @  20.3.2007,  21:52 Найти цитируемый пост)
Только по моему не обедающие, а голодные философы

Ну не я придумал название, а нам так его дали... smile
PM   Вверх
ama_kid
Дата 20.3.2007, 22:57 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

Репутация: 9
Всего: 95



Цитата(Pakshin A. S. @  20.3.2007,  21:36 Найти цитируемый пост)
А OpenSemaphore() не нужно выполнять? 

Ну, если ты уж ввел семафоры, то можно. Вот примерно так - теперь по два философа едят одновременно за столом:
Код

unit U_Restaurant;

interface

uses
  Classes, Windows, StdCtrls, SysUtils;

type
  TPhilosoph = class(TThread)
  public
    id: integer;
    FLabels: array [1..5] of TLabel;
  private
    i, j: integer;
    procedure SetForksR;
    procedure SetForksL;
    procedure FreeForks;
  protected
    procedure Execute; override;
  end;

var
  _Philosophiers: array [1..5] of TPhilosoph;

procedure InitializeRestaurant;

implementation

var
  CanEat: THandle;
  Forks: array [1..5] of THandle;

procedure TPhilosoph.SetForksR;
begin
  FLabels[i].Caption:=IntToStr(id);
  OpenMutex(MUTEX_ALL_ACCESS,false,PAnsiChar('Вилка '+IntToStr(i)));
end;

procedure TPhilosoph.SetForksL;
begin
  FLabels[j].Caption:=IntToStr(id);
  OpenMutex(MUTEX_ALL_ACCESS,false,PAnsiChar('Вилка '+IntToStr(j)));
end;

procedure TPhilosoph.FreeForks;
begin
  FLabels[i].Caption:='0';
  FLabels[j].Caption:='0'
end;

procedure TPhilosoph.Execute;
var
  find: boolean;
begin
  while not Terminated do
    begin
      if WaitForSingleObject(CanEat, INFINITE) = WAIT_OBJECT_0 then
        begin
          OpenSemaphore(1,false,'Философы у стола');
          (* Ищем вилку в правую руку *)
          i:=1;
          find:=false;
          while not find do
            begin
              if WaitForSingleObject(Forks[i], 0) = WAIT_OBJECT_0 then
                begin
                  Synchronize(SetForksR);
                  find:=true
                end
              else
                begin
                  inc(i);
                  if i >= 6 then
                    i:=1
                end
            end;
          (* Ждем вилку в левую руку *)
          j:=i + 1;
          if j >= 6 then
            j:=1;
          if WaitForSingleObject(Forks[j], INFINITE) = WAIT_OBJECT_0 then
            begin
              Synchronize(SetForksL);
              Sleep(3000); // кушаем
              Synchronize(FreeForks)
            end;
          ReleaseMutex(Forks[j]);
          ReleaseMutex(Forks[i])
        end;
      ReleaseSemaphore(CanEat, 1, nil)
    end
end;

procedure InitializeRestaurant;
var
  i: integer;
begin
  CanEat:=CreateSemaphore(nil, 3, 3, 'Философы у стола');
  for i:=1 to 5 do
    Forks[i]:=CreateMutex(nil, false, PAnsiChar('Вилка '+IntToStr(i)));
end;

end.


Это сообщение отредактировал(а) ama_kid - 20.3.2007, 23:01


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
Mistris
Дата 21.4.2007, 14:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 21.4.2007

Репутация: нет
Всего: нет



а у кого-нибудь есть эта программа написанная на С++?
очень нужна
PM MAIL   Вверх
Alexeis
Дата 21.4.2007, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Mistris, странный вопрос в разделе Delphi smile 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

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

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0710 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.