Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.10.2010, 20:22   #1
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию разобраться в программе

Здравствуйте. Программа непонятно работает при пошаговом выполнении.
Если поставить Брейки в выделенных местах и затем выполнять пошагово, то выводит
что-то в консоль, хотя в выполняемой строке нет и близко Write или writeln.
Здесь потоки обращаются к массиву, что-то меняют в нём, и в конце выдается массив с
которым поработали потоки. Кто-нибудь может помочь мне подробно разобраться в этом коде. Это полный код.
Код:
{$APPTYPE CONSOLE}
{Реализовать семафор на основе объекта синхронизации «событие». Количественные 
характеристики семафора должны быть аналогичны соответствующему объекту ядра типа семафор.}
program laba_1_4;
uses
  Windows;
type TMySemaphore = record //Семафор
                      HEvent: THandle; // Событие 
                      Count: cardinal; // Сколько еще можно внести потоков
                      Max: Cardinal;  // Максимальное количество потоков
                      waiting: cardinal; // Сколько потоков ждёт
                    end;
var h: array[1..5] of Thandle; //Дескрипторы потоков
    d: array[1..5] of cardinal; // Идентификаторы потоков
    Q: array[1..10] of integer; //Общий ресурс
    i: word;
    dwError: DWORD;
    hlocal: LPTSTR;
    Sem: TmySemaphore;

procedure CreateMySemaphore(var S: TMySemaphore; init, max: integer; name: string);
begin
  S.Count := init;
  S.Max := Max;
  if init > max then
  begin
    writeln('Start value must be less then maximal');
    readln;
    halt;
  end;
  S.HEvent := CreateEvent(nil,false,true,PChar(name));
  s.waiting := 0;
end;

procedure WaitForMySemaphore(var S:TMySemaphore);
begin
  if s.Count > 0 then
    dec(S.Count)
  else
  begin
    inc(s.waiting);
    WaitForSingleObject(S.HEvent,INFINITE);
  end;
end;

procedure ReleaseMySemaphore(var S:TMySemaphore);
begin
  if S.Count = 0 then
    SetEvent(S.HEvent);
  if S.waiting > 0 then
    dec(S.waiting)
  else
    inc(S.Count);
  if S.Count > S.Max then
    writeln('Too many!!');
end;

procedure CloseMySemaphore(var S:TMySemaphore);
begin
  CloseHandle(S.HEvent);
end;

function proc1(dd:dword):dword; stdcall;
 var X,i,j,ip:integer;
     id:dword;
begin
  id := GetCurrentThreadId();
  ip := 0;
  for i := 1 to 5 do
    if d[i] = id then
      ip := i;
  for i := 1 to 5 do
  begin
    
    writeln(ip,' Can enter:',Sem.Count,' Are waiting:',Sem.waiting);
    writeln(ip,' is waiting');
    WaitForMySemaphore(Sem);
    sleep(1000);
    writeln(ip,' CanEnter:',Sem.Count,' Are waiting:',Sem.waiting);
    j := random(10) + 1;//[1..10]
    x := random(100);
    
    writeln(ip,' Thread#',ip,' has put a number into place:',j,'-',X);
    Q[j] := x;
    writeln(ip,' Can enter:',Sem.Count,' Are waiting:',Sem.waiting);
    sleep(1000);
    ReleaseMySemaphore(Sem);
    writeln(ip,' Releasing');
    writeln(ip,' Can enter:',Sem.Count,' Are waiting:',Sem.waiting);
  end;
  result := 0;
end;

function proc2(dd:dword):dword; stdcall;
var i,j,X,ip:integer;
     id:dword;
begin
  id := GetCurrentThreadId();
  ip := 0;
  for i := 1 to 5 do
    if d[i] = id then
      ip := i;
  for i := 1 to 15 do
  begin
    
    writeln(ip,' Can enter:',Sem.Count,' Are waiting:',Sem.waiting);
    writeln(ip,' Waiting');
    WaitForMySemaphore(Sem);
    sleep(1000);
    writeln(ip,' Can enter:',Sem.Count,' Are waiting:',Sem.waiting);
    j := random(10) + 1; 
    x := Q[j];
   
    writeln(ip,' Thread#',ip,' has got a number from place:',j,'-',X);
    writeln(ip,' Can enter:',Sem.Count,' Are waiting:',Sem.waiting);
    sleep(1000);
    ReleaseMySemaphore(Sem);
    writeln(ip,' Releasing');
    writeln(ip,' Can enter:',Sem.Count,' Are waiting:',Sem.waiting);
  end;
  proc2 := 0;
end;


Begin
  randomize;

  write('Was:');
  for i := 1 to 10 do
  begin
    q[i] := random(100);
    write(q[i],' ');
  end;
  writeln;
  CreateMySemaphore(Sem,3,3,'EventSemaphore');
  for i := 1 to 3 do
  begin
    h[i] := CreateThread(nil,0,@proc1,nil,0,d[i]);
    if h[i] = 0 then
      writeln(GetLastError)
    else
  end;
  for i := 4 to 5 do
  begin
    h[i] := CreateThread(nil,0,@proc2,nil,0,d[i]);
    dwError := GetLastError;
    if h[i] = 0 then
      writeln(dwError)
    
    else
  end;
  WaitForMultipleObjects(5,@h,true,INFINITE);
  for i := 1 to 5 do
    CloseHandle(h[i]);
  CloseMySemaphore(Sem);
  write('Is:'); 
  for i := 1 to 10 do 
  begin
    write(q[i],' ');
  end;
  readln;
End.
начиная от выделенных
Ищущий да обрящет

Последний раз редактировалось fredwriter; 09.10.2010 в 20:40.
fredwriter вне форума Ответить с цитированием
Старый 09.10.2010, 20:38   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Если поставить Брейки в выделенных местах
Где? В каких местах ты ставишь?
Насколько я вижу вывод на экран происходит в процедурах потоков, так что вполне нормально если ты ставишь бряк на главный поток, а остальные потоки то продолжать отработку должны без проблем и остановок - это же потоки.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 09.10.2010, 20:39   #3
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

Щас поправлю Забыл места выделить

Кто-нибудь может попроще объяснить, что происходит в программе, а то я понимаю её урывками: там понимаю, тут не понимаю. как в кино.

Понятно, что потоки что-то делают с массивом. Что такое семафор - это объект синхронизации, который следит за тем, чтобы к общему ресурсу не смогли одновременно получить доступ более n потоков. А как в этой программе это работает. Событие - это объект синхронизации, который позволяет потоку продолжить работу при наступлении определенного события. Помогите разобраться. По отдельности каждая процедура вроде понятно, что делает, кроме двух функций, одна Proc1 - функция добавляющих потоков(что значит добавляющих и что она делает), а вторая Proc2 - процедура вынимающего потока(аналогично). И в целом что делает программа не понятно.
Ищущий да обрящет

Последний раз редактировалось Stilet; 09.10.2010 в 22:24.
fredwriter вне форума Ответить с цитированием
Старый 09.10.2010, 22:25   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
может попроще объяснить, что происходит в программе
Я пас... В такие наночь вникать - к кошмарам... Без обид конечно.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 10.10.2010, 04:54   #5
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

Ну, может быть, с утреца, как нибудь, или днём?
Ищущий да обрящет

Последний раз редактировалось fredwriter; 10.10.2010 в 05:09.
fredwriter вне форума Ответить с цитированием
Старый 10.10.2010, 10:19   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Ну, может быть, с утреца, как нибудь, или днём?
может быть, может быть..

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

Скажите, а Ведь Вы не сами писали эту программу?!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 10.10.2010, 10:47   #7
fredwriter
Форумчанин
 
Регистрация: 06.10.2009
Сообщений: 121
По умолчанию

Если бы я писал её сам, я бы не спрашивал как она работает. Для написания такой программы мне не хватает знаний видимо.
Ищущий да обрящет
fredwriter вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Коментарии к программе savra Помощь студентам 4 13.01.2010 01:32
Помогите разобраться в программе... Tee Jay Помощь студентам 0 25.06.2009 19:20
помогите разобраться в программе iwaniwan Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 0 15.04.2009 19:38
Помогите разобраться в программе Gekada Общие вопросы C/C++ 1 09.12.2008 19:23