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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 15.04.2012, 09:38   #1
phasha
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 130
Вопрос как заставить функцию ждать?

нам задали сделать условный макет обработки потоков ПИСАТЕЛЬ-ЧИТАТЕЛЬ, где каждый из них может писать или читать разное колличество потоков.вопрос в том что в функции где идет вычитание нужно заставить ее ЖДАТЬ если, допустим блокирующая переменная ровна нулю, пока это не представиться возможным
Код:
program simofor;

{$APPTYPE CONSOLE}

uses
  SysUtils;
  function p(var x:integer):Integer;  //óìåíüøåíèå íà 1
    begin
       if x>0 then
        Dec(x);    //åñëè ìîæíî óâåëè÷èòü-óâåëè÷èâàåì

    end;

  function v(var x:integer):Integer;//óâåëè÷åíèå íà 1
    begin
      inc(x);
    end;
             //ÏÈÑÀÒÅËÜ
  procedure PISATEL(var empty,block,k,full:integer;
  var och,potok:array of integer);

  begin

   p(empty);                       //âûäåëÿåì ÿ÷åéêó
                                   //åñëè ÿ÷åéêè åñòü ñâîáîäíûå òî
      p(block);                    //ñòàâèì áëîê
                                   //åñëè ïðîøåë, òî
         och[k]:=potok[k];         //ïèøåì â î÷åðåäü
        potok[k]:=0;               //îñâîáîæäàåì ïðîñåññ

         v(block);                 //îòïóñêàåì áëîê

         v(full);                  //âûñâîáîæäàåì çàíÿòóþ ÿ÷åéêó

  end;
             //×ÈÒÀÒÅËÜ
  procedure CHITATEL(var empty,block,k,full:integer;
  var och,Gotov:array of integer);

  begin
      p(full);                    //çàíèìàåì ÿ÷åéêó

      p(block);                   //ñòàâèì áëîê


          Gotov[k]:=och[k];       //âûòàñêèâàåì èç î÷åðåäè è
          och[k]:=0;              //îñâîáîæäàåì î÷åðåäü

          v(block);               //îòïóñêàåì áëîê

          v(empty);               //âîçâðàùàåì ÿ÷åéêó

  end;

var
  i:Integer;                     
  n:Integer;                     
  nom:Integer;                    
  k:Integer;                    
  empty:Integer;                  
  full:integer;                  
  block:Integer;                
  pis,chit:integer;              
  Potok:array [0..100] of Integer;
  och:array[0..100] of Integer;               
  Gotov:array [0..100] of Integer;
begin
  empty:=100;       
  full:=0;          
  block:=1;        
  pis:=1;
  chit:=1;

    Randomize;   n:=0;           
    k:=0;

      while 1=1 do begin

      for i:=0 to 100 do begin
       Potok[i]:=Random(4000)+1;    

       Gotov[i]:=0;               
          end;

       nom:=100;

    repeat







    PISATEL(empty,block,k,full,och,potok);

                         

    CHITATEL(empty,block,k,full,och,Gotov);

    write('process #',k); Sleep(100);
    write(' .');sleep(100);write('.');Sleep(100);write('.');
    Sleep(100);write(' - ',gotov[k]); Writeln;

       Inc(k);    Dec(nom) ;
    until nom=0;
    k:=0;              

    end;

  Readln;
end.
функция P(x) просто не представляю как заставить ее ждать без ошибок((
phasha вне форума Ответить с цитированием
Старый 15.04.2012, 09:58   #2
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Код:
вопрос в том что в функции где идет вычитание нужно заставить 
ее ЖДАТЬ если, допустим блокирующая переменная ровна нулю, 
пока это не представиться возможным
Что за блокирующая переменная такая?
Может так:
Код:
repeat 
if блокирующая переменная=0 sleep(200)
else какая-то процедура, которая должна изменять значение блокирующей переменной
until (какое-то условие);
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 15.04.2012, 15:51   #3
phasha
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 130
По умолчанию

спасибо я попробую таким путем но не уверен что так будет правильно.а блокирующая переменная это переменная открывающая и закрывающая вход процесса в обработку))может как то не правильно сказал но суть та же))еще раз спасибо!
phasha вне форума Ответить с цитированием
Старый 15.04.2012, 19:53   #4
Rin
Негодник
Форумчанин
 
Аватар для Rin
 
Регистрация: 10.11.2009
Сообщений: 880
По умолчанию

Что-то сразу до меня не дошло. Все гораздо проще.
сделайте глобальную переменную my_simafor:boolean, которая будет принимать значение 1, если что-то ещё не прочитано, и 0, если прочитано. а в функции function p(var x:integer):Integer;
в самом начале запишите if my_simafor then exit;
Если помог, проси поставить минус. Будь оригинален!
Rin вне форума Ответить с цитированием
Старый 15.04.2012, 20:44   #5
phasha
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 130
По умолчанию

я несколько изменил код и теперь обрабатывает не по одному а по 50 и вроде все правильно
Код:
program simofor;

{$APPTYPE CONSOLE}

uses
  SysUtils;
  function p(var x:integer):Integer;
    begin 
       if x>0 then
        Dec(x)  else
          repeat
           begin
         Sleep(2000);
         inc(x);
         end;
       until x>0;

    end;

  function v(var x:integer):Integer;
    begin
      inc(x);
    end;
             //ÏÈÑÀÒÅËÜ
  procedure PISATEL(var empty,block,full:integer;
  var och,potok:array of integer;var x:integer);
   var a,i:integer;
  begin
    if empty>0 then begin
      a:=x;
   for i:=a to a+50 do begin
   p(empty);

      p(block);

         och[i]:=potok[i];
        potok[i]:=0;
           if och[i]<>0 then begin
         write('Pisatel-process #',i); Sleep(90);
    write(' .');sleep(90);write('.');Sleep(90);write('.');
    Sleep(90);write(' - ',och[i],'  empty: ',empty,'; full: ',full); Writeln;
         v(block);                

         v(full);
             end;          
     end;
         if x<>100 then
     x:=x+50 else x:=0;               end;
  end;
             //×ÈÒÀÒÅËÜ
  procedure CHITATEL(var empty,block,full:integer;
  var och,Gotov:array of integer;var x:Integer);
  var a,i:Integer;
  begin
    if full>0 then begin
    a:=x;

    for i:=a to a+50 do begin
      p(full);                  

      p(block);                  


          Gotov[i]:=och[i];       
          och[i]:=0;            
           if Gotov[i]<>0 then begin
           write('Chitatel-process #',i); Sleep(90);
    write(' .');sleep(90);write('.');Sleep(90);write('.');
    Sleep(90);write(' - ',gotov[i],'  empty: ',empty,'; full: ',full); Writeln;
                end;
          v(block);             

          v(empty);


     end;
     if x<>100 then
     x:=x+50 else x:=0;
          end;
  end;

var
  i,nom:Integer;                      
  empty:Integer;                 
  full:integer;                  
  block:Integer;                  
  pis,chit:integer;              
  Potok:array [0..100] of Integer;
  och:array[0..100] of Integer;                 
  Gotov:array [0..100] of Integer;
begin
  empty:=100;       
  full:=1;          
  block:=0;         
  pis:=0;
  chit:=0;

    Randomize;              


      while 1=1 do begin

      for i:=0 to 100 do begin
       Potok[i]:=Random(4)+1;    

       Gotov[i]:=0;                 
          end;

       nom:=2;

    repeat







    PISATEL(empty,block,full,och,potok,pis);

     Writeln(#13);

    CHITATEL(empty,block,full,och,Gotov,chit);
     Writeln(#13);


           Dec(nom) ;
    until nom=0;
     pis:=0;
     chit:=0;

    end;

  Readln;
end.
сейчас еще подправлю
phasha вне форума Ответить с цитированием
Старый 15.04.2012, 20:52   #6
phasha
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 130
По умолчанию

Код:
program simofor;

{$APPTYPE CONSOLE}

uses
  SysUtils;
  function p(var x:integer;xx:boolean):Integer;
    begin
      if xx then Exit;
       if x>0 then
        Dec(x) ; {else
          repeat
           begin
         Sleep(2000);
         inc(x);
         end;
       until x>0;  }

    end;

  function v(var x:integer):Integer;
    begin
      inc(x);
    end;
             //ÏÈÑÀÒÅËÜ
  procedure PISATEL(var empty,block,full:integer;
  var och,potok:array of integer;var x:integer;var xx:Boolean);
   var a,i:integer;
  begin
    if empty>0 then begin
      a:=x;
   for i:=a to a+50 do begin
   p(empty,xx);

      p(block,xx);

         och[i]:=potok[i];
        potok[i]:=0;
           if och[i]<>0 then begin
         write('Pisatel-process #',i); Sleep(90);
    write(' .');sleep(90);write('.');Sleep(90);write('.');
    Sleep(90);write(' - ',och[i],'  empty: ',empty,'; full: ',full); Writeln;
         v(block);                 //îòïóñêàåì áëîê

         v(full);
             end;          //âûñâîáîæäàåì çàíÿòóþ ÿ÷åéêó
     end;
         if x<>100 then
     x:=x+50 else x:=0;
               xx:=False;
             end;

  end;
             //×ÈÒÀÒÅËÜ
  procedure CHITATEL(var empty,block,full:integer;
  var och,Gotov:array of integer;var x:Integer;var xx:boolean);
  var a,i:Integer;
  begin
    if full>0 then begin
    a:=x;

    for i:=a to a+50 do begin
      p(full,xx);                    //çàíèìàåì ÿ÷åéêó

      p(block,xx);                   //ñòàâèì áëîê


          Gotov[i]:=och[i];       //âûòàñêèâàåì èç î÷åðåäè è
          och[i]:=0;              //îñâîáîæäàåì î÷åðåäü
           if Gotov[i]<>0 then begin
           write('Chitatel-process #',i); Sleep(90);
    write(' .');sleep(90);write('.');Sleep(90);write('.');
    Sleep(90);write(' - ',gotov[i],'  empty: ',empty,'; full: ',full); Writeln;
                end;
          v(block);               //îòïóñêàåì áëîê

          v(empty);


     end;
     if x<>100 then
     x:=x+50 else x:=0;
     xx:=true;
          end;
  end;

var
  i,nom:Integer;                      //íóìåðàöèÿ ìàññèâà
  empty:Integer;                  //êîëè÷åñòâî ñâîáîäíûõ ÿ÷ååê
  full:integer;                   //ïðîöåññ
  block:Integer;                  //âëîêèðóþùàÿ ïåðåìåííàÿ
  pis,chit:integer;               //ïåðåìåííûå äëÿ çàïîìèíàíèÿ êóðñîðà ÷èò è ïèñ
  My_simofor:boolean;
  Potok:array [0..100] of Integer;//ìàññèâ ïðîöåññîâ
  och:array[0..100] of Integer;                 //(î÷åðåäü)
  Gotov:array [0..100] of Integer;//ìàññèâ âûïîëíåííûõ ïðîöåññîâ(äëÿ ïðîâåðêè)
begin
  empty:=100;       // íà÷àëüíûå
  full:=1;          // äàííûå
  block:=0;         // ñèñòåìû
  pis:=0;
  chit:=0;

    Randomize;                //ïîêà êîë-âî îøèáîê 0


      while 1=1 do begin

      for i:=0 to 100 do begin
       Potok[i]:=Random(4)+1;    //  ýìóëèðóåì ïîòîê ãäå íåò íóëåé

       Gotov[i]:=0;                 //  ïðîøåäøèõ ïðîöåññîâ íåò
          end;

       nom:=2;

    repeat







    PISATEL(empty,block,full,och,potok,pis,My_simofor);

     Writeln(#13);

    CHITATEL(empty,block,full,och,Gotov,chit,My_simofor);
     Writeln(#13);


           Dec(nom) ;
    until nom=0;
     pis:=0;
     chit:=0;

    end;

  Readln;
end.
сделал как вы сказали, empty сошел с ума))
phasha вне форума Ответить с цитированием
Старый 15.04.2012, 20:57   #7
phasha
Форумчанин
 
Регистрация: 24.03.2011
Сообщений: 130
По умолчанию

кажется понял.нужно не по 50 писать а столько сколько у нас свободных ячеек empty. потом читать при empty=0 освобождая на каждое место))точно!нужно было предусмотреть то что у нас может не хватить памяти на все процессы и организовать поочередные выполненяи ВСЕХ процессов!!! спасибо!
Код:
program simofor;

{$APPTYPE CONSOLE}

uses
  SysUtils;
  function p(var x:integer;xx:boolean):Integer;
    begin
      
       if x>0 then
        Dec(x) ;// if xx=true then Exit;
       {else   repeat
           begin
         Sleep(2000);
         inc(x);
         end;
       until x>0;  }

    end;

  function v(var x:integer):Integer;
    begin
      inc(x);
    end;
             //ÏÈÑÀÒÅËÜ
  procedure PISATEL(var empty,block,full:integer;
  var och,potok:array of integer;var x:integer;var xx:Boolean);

  begin
    if empty>0 then begin

          while empty<>-1 do begin


   p(empty,xx);

      p(block,xx);

         och[x]:=potok[x];
        potok[x]:=0;
           if och[x]<>0 then begin
         write('Pisatel-process #',x); Sleep(90);
    write(' .');sleep(90);write('.');Sleep(90);write('.');
    Sleep(90);write(' - ',och[x],'  empty: ',empty,'; full: ',full); Writeln;
      end;
         v(block);

         v(full);

        inc(x);
        if empty=0 then  Exit;
     end;

               xx:=False;
             end;

  end;
             //×ÈÒÀÒÅËÜ
  procedure CHITATEL(var empty,block,full:integer;
  var och,Gotov:array of integer;var x:Integer;var xx:boolean);
  begin
    if full>0 then begin


    while empty<>20 do begin
      p(full,xx);                    //çàíèìàåì ÿ÷åéêó

      p(block,xx);                   //ñòàâèì áëîê


          Gotov[x]:=och[x];       //âûòàñêèâàåì èç î÷åðåäè è
          och[x]:=0;              //îñâîáîæäàåì î÷åðåäü
           if Gotov[x]<>0 then begin
           write('Chitatel-process #',x); Sleep(90);
    write(' .');sleep(90);write('.');Sleep(90);write('.');
    Sleep(90);write(' - ',gotov[x],'  empty: ',empty,'; full: ',full); Writeln;
                end;
          v(block);               //îòïóñêàåì áëîê

          v(empty);

     inc(x);
     if empty=20 then  Exit;
     end;

     xx:=true;
          end;
  end;

var
  i,nom:Integer;                      //íóìåðàöèÿ ìàññèâà
  empty:Integer;                  //êîëè÷åñòâî ñâîáîäíûõ ÿ÷ååê
  full:integer;                   //ïðîöåññ
  block:Integer;                  //âëîêèðóþùàÿ ïåðåìåííàÿ
  pis,chit:integer;               //ïåðåìåííûå äëÿ çàïîìèíàíèÿ êóðñîðà ÷èò è ïèñ
  My_simofor:boolean;
  Potok:array [0..100] of Integer;//ìàññèâ ïðîöåññîâ
  och:array[0..100] of Integer;                 //(î÷åðåäü)
  Gotov:array [0..100] of Integer;//ìàññèâ âûïîëíåííûõ ïðîöåññîâ(äëÿ ïðîâåðêè)
begin
  empty:=20;       // íà÷àëüíûå
  full:=1;          // äàííûå
  block:=0;         // ñèñòåìû
  pis:=0;
  chit:=0;

    Randomize;                //ïîêà êîë-âî îøèáîê 0


      while 1=1 do begin

      for i:=0 to 100 do begin
       Potok[i]:=Random(4)+1;    //  ýìóëèðóåì ïîòîê ãäå íåò íóëåé

       Gotov[i]:=0;                 //  ïðîøåäøèõ ïðîöåññîâ íåò
          end;


    PISATEL(empty,block,full,och,potok,pis,My_simofor);

     Writeln(#13);

    CHITATEL(empty,block,full,och,Gotov,chit,My_simofor);
     Writeln(#13);



  if pis=100 then   pis:=0;
  if chit=100 then   chit:=0;

    end;

  Readln;
end.

Последний раз редактировалось phasha; 15.04.2012 в 21:13.
phasha вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как заставить перестать работать функцию ЕСЛИ? MyTHblu Microsoft Office Excel 2 12.04.2012 14:13
как не ждать окончания процедуры(функции)? Кольша Общие вопросы Delphi 14 02.02.2012 16:49
как заставить функцию выполняться при нажатой кнопке мыши Arassir JavaScript, Ajax 3 02.11.2011 17:44
Как передать указатель на функцию в функцию WIN32APIist Общие вопросы C/C++ 1 27.01.2011 10:35
Подскажите, как в консольном приложении заставить программу ждать нажатия клавиши(си)) Александр Елис Помощь студентам 2 19.09.2009 19:38