Párhuzamos folyamatok
(Példák)

Útkereszteződés jobbkéz szabály nélkül – egy „naív” megoldás

Kétirányú haladást lehetővé tevő útról az útkereszteződésben egy olyan egyirányú utca ágazik le jobbra is és balra is, amelybe az útról kis- és nagyívben lehetséges a behajtás. Nincs jobbkéz szabály, sőt sem rendőr, sem lámpa nincs a közelben.

Megoldás:

Program FolyamatSzimulacio_UtKeresztezodes1;

{
     Párhuzamos folyamatok kvázipárhuzamos szimulációja - útkeresztezôdés.

        Elképzelés:

        1. Minden folyamatot egy idôegység alatt végrehajtandó lépések

           sorozatára bontjuk. (Ezek alatt nem kommunikálhatnak egymással.)
           A lépések kódrészeit elkülönítve tartalmazza a 'lepes' metódus.
        2. Hogy éppen melyik lépésnél tart, azt egy attributuma (az 'álla-
           pot' mezôje) tartja nyilván.
        3. Az egyes folyamatok vezérlését a 'keret' metódus végzi.
        4. A teljes rendszer vezérlését a fôprogram végzi, amely idôegysé-
           genként minden folyamatnak átadja egy lépés erejéig a vezérlést.
           Itt jönnek létre az új folyamatok, s itt szünnek meg a végálla-
           potba jutottak.

        A keresztezôdés:

        1. A fôútvonal 2 irányban 1-sávos. (Elôzés nincs.)
        2. A keresztezôdésnél a fôútról csak le lehet kanyarodni, rá nem.
        3. A mellékút 1-sávos.
        4. Megengedett a fôútról való balra és jobbra kanyarodás, ill.
           egyenesen tovább.

        A modell:

        1. Nincs szinkronizáció és ütközés.
        2. Generálás: idôegységenként ... db.
        3. A célkód: K->Ny =+1..+99;  K->E =+101..+199;  K->D =+201..+299
                     Ny->K =-1..-99; Ny->E =-101..-199; Ny->D =-201..-299
        4. A könnyebb adminisztrálás érdekében följegyezzük, hogy a keresz-
           tezôdés egyik-másik sávja foglalt-e.
        5. Foglalt sáv irányba nem lehet elfordulni.

        Várható eredmény:

           Elôbb-utóbb halálos ölelés.

}

  Uses
     Newdelay,Crt;

{
******* Folyamat-típus ****************************************************
                                                                          *
}

  Const
     
VegAllapot = 3; {állapotok: 1='a keresztezôdés elôtt',
                                  2='a keresztezôdésben',
                                  3='a keresztezôdés után'}

  Type
     
Lepesek  = 1..VegAllapot;

  Const
     
SAllapot : Array [Lepesek] of String[5]=
                 ('előtt','ben','után');

  Function AzonToString(azon:Integer{folyamatazonosító}):String;
      Begin
        If
         
(0<azon) and (azon<100)     then AzonToString:='K->Ny' else if
         
(100<azon) and (azon<200)   then AzonToString:='K-> É' else if
         
(200<azon) and (azon<300)   then AzonToString:='K-> D' else if
         
(-100<azon) and (azon<0)    then AzonToString:='Ny->K' else if
         
(-200<azon) and (azon<-100) then AzonToString:='Ny->É' else if
         
(-300<azon) and (azon<-200) then AzonToString:='Ny->D'
        {EndIf}
      End;

  Type
      Folyamat = Object
                    azon: Integer; {folyamatazonosító}
                    allapot: Byte;
                    Constructor indul(Const fa: Byte);
                    Procedure keret;
                    Procedure lepes(Const i: Lepesek);
                    Destructor vege;
                 End;

 

  Constructor Folyamat.indul(Const fa: Byte);
  Begin
  End;

 

  Procedure Folyamat.keret; {az adott folyamat egy -a következô- lépésének
                             vezérlése}
  Begin
  End;

 

  Procedure Folyamat.lepes(Const i: Lepesek);
  Begin
  End;

 

  Destructor Folyamat.vege;
  Begin
  End;

{                                                                       *
******* Folyamat-típus **************************************************
}

Var
    fogl1,fogl2: Boolean; {K->Ny, ill.Ny->K sáv foglalt}

 

{
******* Autó-típus ********************************************************
                                                                          *
}

  Type
      Auto = Object(Folyamat)
               Constructor indul(Const fa: Byte);
               Procedure keret;
               Procedure lepes(Const i: Lepesek);
             End;

 

  Constructor Auto.indul(Const fa: Byte);
  Begin
   
azon:=(Integer(Random(2))*2-1)*(Random(3)*100+fa); {az utolsó 2
                                                        számjegy egyedi}
    allapot:=1;
  End;

 

  Procedure Auto.keret; {az adott folyamat egy -a következô- lépésének
                         vezérlése}
  Begin
    If
allapot=2{kereszteződésben} then HighVideo;
    Writeln(azon:6,'-s  ('+AzonToString(azon)+') autó a(z) ',
            allapot,'. lépést (',SAllapot[allapot],') hajtja végre.');
    If allapot=2{kereszteződésben} then NormVideo;
    Lepes(allapot);
    Inc(allapot);
  End;

 

  Procedure Auto.lepes(Const i: Lepesek);
  Begin
    Case i of
      1: {az 1. lépés kódja:}
         Begin
           If
             ({K->Ny}(azon>0) and (azon<100) and fogl1) or
             ({K->E }(azon>100) and (azon<200) and fogl1) or
             ({K->D }(azon>200) and fogl1) or
             ({Ny->K}(-azon>0) and (-azon<100) and fogl2) or
             ({Ny->E}(-azon>100) and (-azon<200) and fogl2) or
             {Ny->D}(-azon>200) and fogl2
                                     then Dec(allapot) {nem léphet} else if
             {beléphet K-rôl} azon>0 then fogl1:=True
             {beléphet Ny-ról}       else fogl2:=True
           {EndIf};
          End;

      2: {a  2. lépés kódja:}
         Begin
           If
             ({K->D }(azon>200) and fogl2) or
             ({Ny->E}(-azon>100) and (-azon<200) and fogl1)
                                 then Dec(allapot) {nem léphet} else if
             {K-rôl jött} azon>0 then fogl1:=False {kiléphet}
             {Ny-ról jött}       else fogl2:=False {kiléphet}
           {EndIf};
         End;

    End;
  End;

 

{                                                                       *
******* Autó-típus ******************************************************
}

  Const
     MaxN  = 10;

  Type
    
Autok = Array [1..MaxN] of Auto;

  Var
  {a rendszer állapotparaméterei:}
     F : Autok;
     N : Byte;          {aktív folyamatok száma}
     i,T : Integer;
  {a rendszer bemenôparaméterei:}
     P : Real;          {új folyamat születésének valószínüsége}
     SzulVarSzam: Byte; {az egyszerre születô folyamatok várható száma}
  {a rendszer kimenôparamétere:}

     DbF: Integer;      {összesen generált folyamatok száma}
     c  : Char;

  Const
     Esc = #27;

  {
  **** história-típus ****************************************************
                                                                         *
  }

  Var
    
h : Text;          {egy sora: T:4+':'+azon:10+'='+allapot:4}

  Const
    
fnev = 'folyamat'; {história-file "vezetékneve"}

     Procedure FileNyit;
       Begin
        
Assign(h,fnev+'.hst'); ReWrite(h);
         Writeln(h,' Idö        Autó          Allapot');
       End{FileNyit};

     Procedure Rogzit(Const f: Autok; n: Integer);
       Var
         sor,s1,s2: String;
         i : Byte;
       Begin
         Str(T:4,sor); Writeln(h,sor);
         For i:=1 to n do
         Begin
           sor:='   ';
           Str(f[i].azon:10,s1); Str(f[i].allapot:4,s2);
           sor:=sor+':'+s1+' ('+AzonToString(f[i].azon)+')'
                +'='+s2+' ('+SAllapot[f[i].allapot]+')';
           Writeln(h,sor);
         End;
       End{Rogzit};

     Procedure FileZar;
       Begin
         Close(h);
       End{FileZar};

  {                                                                      *
  **** história-típus ****************************************************
  }

 

  Procedure General(Var fk: Autok; Var n: Byte; Const db: Byte);
    Var
     
i: Byte;
  Begin
   
i:=1;
    While (i<=db) and (n+i<MaxN) do
    Begin
     
Inc(DbF); fk[n+i].indul(DbF); Inc(i);
    End;
   
n:=n+i-1;
  End;

 

  Procedure Takarit(Var fk: Autok; Var n: Byte);
    Var
     
i,db: Byte;
  Begin
   
db:=0;
    For i:=1 to N do
    Begin
      If
fk[i].allapot=VegAllapot then
      Begin
       
Writeln(fk[i].azon:6,'-s  ('+AzonToString(fk[i].azon),
                ') autó a(z) ',fk[i].allapot,'. lépést (',
                SAllapot[fk[i].allapot],') hajtja végre.');
        fk[i].vege;
      End
        else
      Begin
       
Inc(db); fk[db]:=fk[i];
      End;
    End;
    n:=db;
  End;

 

Begin {a rendszer (=folyamatok együttese) kvázipárhuzamos vezérlése:}
  ClrScr;
  FileNyit; {história-file nyitás}
  P:=1.0; SzulVarSzam:=10; fogl1:=False; fogl2:=False;
  DbF:=0;
  T:=1; General(F,N,Random(SzulVarSzam)+2{legálább 5 folyamattal indul});
  Rogzit(f,N); {história-fileba írás}
  c:=' ';
  While (N>0) and (c<>Esc) do
  Begin
   
Writeln('T:':75,T:4);
    Takarit(F,N);
    For i:=1 to N do F[i].keret;
    If Random<P then Begin General(F,N,Random(SzulVarSzam)); End;
   
Inc(T);
    Rogzit(f,N); {história-fileba írás}
    c:=ReadKey;
  End;
 
FileZar; {história-file zárás}
End.

A história-file

… a KERESZT1.EXE demó futás (és „erőszakos” kilépés) után…:

 

 Idő        Autó          Állapot

   1

   :         1 (K->Ny)=   1 (előtt)

   :        -2 (Ny->K)=   1 (előtt)

   2

   :         1 (K->Ny)=   2 (ben)

   :        -2 (Ny->K)=   2 (ben)

   :        -3 (Ny->K)=   1 (előtt)

   :      -104 (Ny->É)=   1 (előtt)

   :      -105 (Ny->É)=   1 (előtt)

   3

   :         1 (K->Ny)=   3 (után)

   :        -2 (Ny->K)=   3 (után)

   :        -3 (Ny->K)=   2 (ben)

   :      -104 (Ny->É)=   1 (előtt)

   :      -105 (Ny->É)=   1 (előtt)

   4

   :        -3 (Ny->K)=   3 (után)

   :      -104 (Ny->É)=   2 (ben)

   :      -105 (Ny->É)=   1 (előtt)

   :       106 (K-> É)=   1 (előtt)

   :         7 (K->Ny)=   1 (előtt)

   :       208 (K-> D)=   1 (előtt)

   :        -9 (Ny->K)=   1 (előtt)

   :       -10 (Ny->K)=   1 (előtt)

   :        11 (K->Ny)=   1 (előtt)

   5

   :      -104 (Ny->É)=   3 (után)

   :      -105 (Ny->É)=   2 (ben)

   :       106 (K-> É)=   2 (ben)

   :         7 (K->Ny)=   1 (előtt)

   :       208 (K-> D)=   1 (előtt)

   :        -9 (Ny->K)=   1 (előtt)

   :       -10 (Ny->K)=   1 (előtt)

   :        11 (K->Ny)=   1 (előtt)

   :        12 (K->Ny)=   1 (előtt)

   6

   :      -105 (Ny->É)=   2 (ben)

   :       106 (K-> É)=   3 (után)

   :         7 (K->Ny)=   2 (ben)

   :       208 (K-> D)=   1 (előtt)

   :        -9 (Ny->K)=   1 (előtt)

   :       -10 (Ny->K)=   1 (előtt)

   :        11 (K->Ny)=   1 (előtt)

   :        12 (K->Ny)=   1 (előtt)

   :      -213 (Ny->D)=   1 (előtt)

   7

   :      -105 (Ny->É)=   2 (ben)

   :         7 (K->Ny)=   3 (után)

   :       208 (K-> D)=   2 (ben)

   :        -9 (Ny->K)=   1 (előtt)

   :       -10 (Ny->K)=   1 (előtt)

   :        11 (K->Ny)=   1 (előtt)

   :        12 (K->Ny)=   1 (előtt)

   :      -213 (Ny->D)=   1 (előtt)

   :       -14 (Ny->K)=   1 (előtt)

   8

   :      -105 (Ny->É)=   2 (ben)

   :       208 (K-> D)=   2 (ben)

   :        -9 (Ny->K)=   1 (előtt)

   :       -10 (Ny->K)=   1 (előtt)

   :        11 (K->Ny)=   1 (előtt)

   :        12 (K->Ny)=   1 (előtt)

   :      -213 (Ny->D)=   1 (előtt)

   :       -14 (Ny->K)=   1 (előtt)

   :        15 (K->Ny)=   1 (előtt)

   9

   :      -105 (Ny->É)=   2 (ben)

   :       208 (K-> D)=   2 (ben)

   :        -9 (Ny->K)=   1 (előtt)

   :       -10 (Ny->K)=   1 (előtt)

   :        11 (K->Ny)=   1 (előtt)

   :        12 (K->Ny)=   1 (előtt)

   :      -213 (Ny->D)=   1 (előtt)

   :       -14 (Ny->K)=   1 (előtt)

   :        15 (K->Ny)=   1 (előtt)

  10

   :      -105 (Ny->É)=   2 (ben)

   :       208 (K-> D)=   2 (ben)

   :        -9 (Ny->K)=   1 (előtt)

   :       -10 (Ny->K)=   1 (előtt)

   :        11 (K->Ny)=   1 (előtt)

   :        12 (K->Ny)=   1 (előtt)

   :      -213 (Ny->D)=   1 (előtt)

   :       -14 (Ny->K)=   1 (előtt)

   :        15 (K->Ny)=   1 (előtt)

  11

   :      -105 (Ny->É)=   2 (ben)

   :       208 (K-> D)=   2 (ben)

   :        -9 (Ny->K)=   1 (előtt)

   :       -10 (Ny->K)=   1 (előtt)

   :        11 (K->Ny)=   1 (előtt)

   :        12 (K->Ny)=   1 (előtt)

   :      -213 (Ny->D)=   1 (előtt)

   :       -14 (Ny->K)=   1 (előtt)

   :        15 (K->Ny)=   1 (előtt)

  12

   :      -105 (Ny->É)=   2 (ben)

   :       208 (K-> D)=   2 (ben)

   :        -9 (Ny->K)=   1 (előtt)

   :       -10 (Ny->K)=   1 (előtt)

   :        11 (K->Ny)=   1 (előtt)

   :        12 (K->Ny)=   1 (előtt)

   :      -213 (Ny->D)=   1 (előtt)

   :       -14 (Ny->K)=   1 (előtt)

   :        15 (K->Ny)=   1 (előtt)

  13

   :      -105 (Ny->É)=   2 (ben)

   :       208 (K-> D)=   2 (ben)

   :        -9 (Ny->K)=   1 (előtt)

   :       -10 (Ny->K)=   1 (előtt)

   :        11 (K->Ny)=   1 (előtt)

   :        12 (K->Ny)=   1 (előtt)

   :      -213 (Ny->D)=   1 (előtt)

   :       -14 (Ny->K)=   1 (előtt)

   :        15 (K->Ny)=   1 (előtt)

  14

   :      -105 (Ny->É)=   2 (ben)

   :       208 (K-> D)=   2 (ben)

   :        -9 (Ny->K)=   1 (előtt)

   :       -10 (Ny->K)=   1 (előtt)

   :        11 (K->Ny)=   1 (előtt)

   :        12 (K->Ny)=   1 (előtt)

   :      -213 (Ny->D)=   1 (előtt)

   :       -14 (Ny->K)=   1 (előtt)

   :        15 (K->Ny)=   1 (előtt)

Egy tökéletesebb megoldás

Lényeg: szemaforral védjük a közösen használt kereszteződést.

Megoldás:

Program FolyamatSzimulacio_UtKeresztezodes2;
{
    Párhuzamos folyamatok kvázipárhuzamos szimulációja,
    szemaforos szinkronizációval.


                        - útkeresztezôdés –


    Elképzelés:

    1. Minden folyamatot egy idôegység alatt végrehajtandó lépések
       sorozatára bontjuk. (Ezek alatt nem kummunikálhatnak egymással.)
       A lépések kódrészeit elkülönítve tartalmazza a 'lepes' metódus.
    2. Az, hogy éppen melyik lépésnél tart, azt egy attributuma (az 'ál-
       lapot' mezôje) tartja nyilván.
    3. Az egyes folyamatok vezérlését a 'keret' metódus végzi.
    4. A teljes rendszer vezérlését a fôprogram végzi, amely idôegysé-
       genként minden folyamatnak átadja egy lépés erejéig a vezérlést.
       Az inaktív -a szemaforoknál várakozó- folyamatok közül csak az
       elsôvel történhet valami (továbbléphet, vagy még várakozni kény-
       szerül).
    5. A fôprogramban jönnek létre az új folyamatok, s itt szünnek meg a
       végállapotba jutottak.
 
  6. A szemaformüveletek önálló, elemi müveleteknek számítanak. A sze-
       mafor P-müveletét két müveletre szedjük:
      a) a "normál" P-müvelet, ami adott esetben a várakozási sorba ál-
         lít; és
      b) a Q-müvelet, amely ellenôrzi a várakozást, s adott esetben to-
         vábbengedi. (Ez utóbbi nem tünik föl az egyedi folyamat lépései
         között, csak a fôfolyamatban.)

    A keresztezôdés:

    1. A fôútvonal 2 irányban 1-sávos. (Elôzés nincs.)
    2. A keresztezôdésnél a fôútról csak le lehet kanyarodni, rá nem.
    3. A mellékút 1-sávos.
    4. Megengedett a fôútról való balra és jobbra kanyarodás, ill.
       egyenesen tovább.

    A modell:

    1. Egyszerü szinkronizáció.
    2. Generálás: idôegységenként ... db.
    3. A célkód: K->Ny =+1..+99;  K->E =+101..+199;  K->D =+201..+299
                 Ny->K =-1..-99; Ny->E =-101..-199; Ny->D =-201..-299
    4. A keresztezôdésben csak egy autó lehet. A belépést szemaforral
       szinkronizáljuk.

    Várható eredmény:

       Nincs halálos ölelés, de meglehtôsen "darabos" az autók áramlása.
}

  Uses
    Newdelay,Crt;

{

******* Folyamat-típus ****************************************************
                                                                          *
}

  Const
     
VegAllapot = 5; {állapotok: 1='a keresztezôdés elôtt',
                                  2='P-müvelet',
                                  4='a keresztezôdésben',
                                  4='V-müvelet',
                                  5='a keresztezôdés után'}

  Type
     
Lepesek  = 1..VegAllapot;
  Const
     
SAllapot : Array [Lepesek] of String[5]=
                 ('előtt','P','ben','V','után');

  Function AzonToString(azon:Integer{folyamatazonosító}):String;
      Begin
        If
         
(0<azon) and (azon<100)     then AzonToString:='K->Ny' else if
         
(100<azon) and (azon<200)   then AzonToString:='K-> É' else if
         
(200<azon) and (azon<300)   then AzonToString:='K-> D' else if
         
(-100<azon) and (azon<0)    then AzonToString:='Ny->K' else if
         
(-200<azon) and (azon<-100) then AzonToString:='Ny->É' else if
         
(-300<azon) and (azon<-200) then AzonToString:='Ny->D'
        {EndIf}
      End;

  Type
      Folyamat = Object
                    azonosito: Integer;
                    allapot: Byte;
                    Constructor indul(Const fa:Integer);
                    Procedure keret;
                    Procedure lepes(Const i:Lepesek);
                 End;

 

{                                                                         *
******* Folyamat-típus ****************************************************
******* Sor-típus *********************************************************
                                                                          *
}

  Const
   
MaxSor = 10;

  Type
   
Ido   =Integer;
    FolAzo=Integer;

    Sor   =Object{Generic=FolAzo}
            hossz,                {sorbeli elem száma}
            eleje,                {az elsô, sorbeli elem indexe}
            vege : -1..MaxSor;    {az utolsó, sorbeli elem indexe}
            elem : Array [0..MaxSor-1] of FolAzo;
            hiba : Boolean;       {az utolsó sormüvelet sikeres volt-e?}
            Constructor inic;
            Procedure Sorba(Const o:FolAzo);
            Procedure Sorbol(Var o:FolAzo);
            Procedure Elso(Var el:FolAzo);
            Function SorHossz:Integer;
          End;

{                                                                         *
******* Sor-típus *********************************************************
******* IdoFolyamatSor-típus **********************************************
                                                                          *
}

  Type
    IdoFolyamatSor=Object
                     ido: Sor{Ido};
                     fol: Sor{FolAzo};
                     Constructor inic;
                     Procedure Sorba(Const i:Ido; Const o:FolAzo);
                     Procedure Sorbol(Var i:Ido; Var o:FolAzo);
                     Procedure Elso(Var i:Ido; Var o:FolAzo);
                     Function SorHossz:Integer;
                   End;

{                                                                         *
******* IdoFolyamatSor-típus **********************************************
******* Szemafor-típus ****************************************************
                                                                          *
}

  Type
    Szemafor=Object
               sz: Integer;
               varoSor: IdoFolyamatSor;     {az inaktív folyamatok sora:
                                             idô + folyamatazonosító}
               Constructor inic;
               Procedure P(Const t:Ido; Var o:Folyamat);
                                            {ha a szemafor=0, akkor a para-
                                             méter Folyamatot a varoSor-ba
                                             teszi, s o.allapot visszalép}
               Procedure Q(Var o:Folyamat); {ha a szemafor>0, akkor a
                                             varoSor-beli elsô Folyamatot
                                             adja vissza,
                                             egyébként "üres-Folyamatot"}
               Procedure V(Const o:Folyamat);
               Function SorHossz:Integer;
             End;

{                                                                         *
******* Szemafor-típus ****************************************************
******* PFolyamat-típus ***************************************************
                                                                          *
}

  Type
    PFolyamat=Object{Generic=Folyamat}
                T  : Word;                {akt. idô}
                aktivSor: IdoFolyamatSor; {az aktív folyamatok sora:
                                           idô + folyamatazonosító}
                Constructor inic;
                Procedure FolyamatSzul;   {folyamatot generál és tesz az
                                           aktívSor utolsó elemévé}
                Procedure MelyFolyamat(Var f:Folyamat; Var j:Integer);
                                        {f.azonosito=>f=ok[j] (ok-tömbbôl)}
    
           Function FolyamatValtozott(Const f:Folyamat; j:Integer):
                                                                Boolean;
                Procedure FolyamatModosit(Const f:Folyamat; j:Integer);
                                          {ok[j]:=f}
                Procedure FolyamatTemet(Const i:Integer);
                Procedure Sorba(Const i:Ido; Const f:Folyamat);
                Procedure Sorbol(Var i:Ido; Var f:Folyamat);
                Procedure Elso(Var i:Ido; Var f:Folyamat);
                Function SorHossz:Integer;
              End;

{                                                                         *
******* PFolyamat-típus ***************************************************
}

  Const
    UresFolyamat : Folyamat=(azonosito:-MaxInt);
    MaxObj = 1000;
    Esc = #27;

 {Az alábbiak a Pascal szerencsétlenségei miatt kerültek ide.
  Az ok, oDb, oUt a késôbbi PFolyamat-hoz tartozik, de mivel a Szemafor is
  használja, ezért ide elôre, globális változóként kerültek.}

  Type
   
Folyamatok = Array [1..MaxObj] of Folyamat;

  Var
   
ok : Folyamatok;                      {az összes folyamat tömbje}
    oDb: 0..MaxObj;                       {az összes folyamat darabszáma}
    oUt: 0..MaxObj;                       {az összes folyamat utolsója}

  Var
    pf: PFolyamat;
    f : Folyamat;
    s : Szemafor;
    P : Real;
    i,j,t,
    SzulVarSzam: Integer;
    c : Char;

 

    Constructor Folyamat.indul(Const fa:Integer);
    Begin
      
azonosito:=fa; allapot:=1;
    End;

 

    Procedure Folyamat.keret; {az adott folyamat egy -a következô-
                               lépésének vezérlése}
    Begin
     
Lepes(allapot);
      Inc(allapot);
    End;

 

    Procedure Folyamat.lepes(Const i:Lepesek);
    Begin
      Case i of
        1: Begin {az 1. lépés kódja}
           End;
        2: Begin {a  2. lépés kódja}
             s.P(pf.T,self);
           End;
        3: Begin {az 3. lépés kódja}
             s.V(self);
           End;
        4: Begin {a  4. lépés kódja}
           End;
      End;
    End;

 

    Constructor Sor.inic;
    Begin
     
hossz:=0; eleje:=0; vege:=-1; hiba:=False
    End{Sor.inic};

 

    Procedure Sor.Sorba(Const o:FolAzo);
    Begin
      If hossz<MaxSor then
      Begin
        Inc(hossz); vege:=(vege+1) Mod MaxSor; elem[vege]:=o
      End
         Else
      Begin
        hiba:=True
      End;
    End{Sor.Sorba};

 

    Procedure Sor.Sorbol(Var o:FolAzo);
    Begin
      If hossz>0 then
      Begin
        Dec(hossz); o:=elem[eleje]; eleje:=(eleje+1) Mod MaxSor;
      End
         Else
      Begin
        hiba:=True
      End;
    End{Sor.Sorbol};

 

    Procedure Sor.Elso(Var el:FolAzo);
    Begin
      If hossz>0 then el:=elem[0]
                 else hiba:=True
    End{Sor.Elso};

 

    Function Sor.SorHossz:Integer;
    Begin
      SorHossz:=hossz
    End{Sor.SorHossz};

 

    Constructor IdoFolyamatSor.inic;
    Begin
      ido.inic; fol.inic;
    End{IdoFolyamatSor.inic};

 

    Procedure IdoFolyamatSor.Sorba(Const i:Ido; Const o:FolAzo);
    Begin
     
ido.Sorba(i); fol.Sorba(o);
    End{IdoFolyamatSor.Sorba};

 

    Procedure IdoFolyamatSor.Sorbol(Var i:Ido; Var o:FolAzo);
    Begin
     
ido.Sorbol(i); fol.Sorbol(o);
    End{IdoFolyamatSor.Sorbol};

 

    Procedure IdoFolyamatSor.Elso(Var i:Ido; Var o:FolAzo);
    Begin
     
ido.Elso(i); fol.Elso(o);
    End{IdoFolyamatSor.Elso};

 

    Function IdoFolyamatSor.SorHossz:Integer;
    Begin
     
SorHossz:=fol.SorHossz
    End{IdoFolyamSor.SorHossz};

 

    Constructor Szemafor.inic;
    Begin
      sz:=1;
      varoSor.inic;
    End{Szemafor.inic};

 

    Procedure Szemafor.P(Const t:Ido; Var o:Folyamat);
    Begin
      If sz=0 then
      Begin
        varoSor.Sorba(t,o.azonosito); Dec(o.allapot)
      End
          Else
      Begin
        sz:=0
      End;
    End{Szemafor.P};

 

    Procedure Szemafor.Q(Var o:Folyamat);
      Var
        t:Ido;
        j:Integer;
    Begin
      If sz=1 then
      Begin
        varoSor.Sorbol(t{nem fontos},o.azonosito);
       {kikerül, s átkerülhet az aktív folyamatok sorába}
        pf.MelyFolyamat(o,j{nem fontos});
      End
         Else
      Begin
        o.azonosito:=UresFolyamat.azonosito
      End;
    End{Szemafor.Q};

 

    Procedure Szemafor.V;
    Begin
      sz:=1
    End{Szemafor.V};

 

    Function Szemafor.SorHossz:Integer;
    Begin
     
SorHossz:=varoSor.SorHossz
    End{Szemafor.SorHossz};

 

    Constructor PFolyamat.inic;
    Begin
     
aktivSor.inic;
      oDb:=0;  {eddig generált folyamatok száma=0}
      oUt:=0;  {eddig generált folyamatok utolsója a "0".}
    End{PFolyamat.inic};

 

    Procedure PFolyamat.FolyamatSzul;
    Begin
     
Inc(oDb);
      Inc(oUt); ok[oUt].indul((Integer(Random(2))*2-1)
                              *(Random(3)*100+oDb));
      aktivSor.Sorba(T,ok[oUt].azonosito);
      {uf: minden generált elem egyedi azonosítóval rendelkezik}
    End{PFolyamat.FolyamatSzul};

 

    Procedure PFolyamat.MelyFolyamat(Var f:Folyamat; Var j:Integer);
                                     {f.azonosito=>f=ok[j] (ok-tömbbôl)}
    Begin
      {ef: van keresett azonosítójú elem}
      j:=1;
      While (ok[j].azonosito<>f.azonosito) do Inc(j);
      f.allapot:=ok[j].allapot
    End{PFolyamat.MelyikFolyamat};

 

    Procedure PFolyamat.FolyamatModosit(Const f:Folyamat; j:Integer);
                                                                {ok[j]:=f}
    Begin
      ok[j]:=f;
    End{PFolyamat.FolyamatModosit};

 

    Function PFolyamat.FolyamatValtozott(Const f:Folyamat;
                                               j:Integer):Boolean;
    Begin
     
FolyamatValtozott:=f.allapot<>ok[j].allapot;
    End{PFolyamat.FolyamatValtozott};

 

    Procedure PFolyamat.FolyamatTemet(Const i:Integer);
      Var
        j:Integer;
    Begin
      For j:=i+1 to oDb do ok[j-1]:=ok[j];
      Dec(oUt);
    End{PFolyamat.FolyamatTemet};

 

    Procedure PFolyamat.Sorba(Const i:Ido; Const f:Folyamat);
    Begin
     
aktivSor.Sorba(i,f.azonosito);
    End{PFolyamatSor.Sorba};

 

    Procedure PFolyamat.Sorbol(Var i:Ido; Var f:Folyamat);
    Begin
     
aktivSor.Sorbol(i,f.azonosito);
      pf.MelyFolyamat(f,j{nem fontos});
    End{PFolyamatSor.Sorbol};

 

    Procedure PFolyamat.Elso(Var i:Ido; Var f:Folyamat);
    Begin
     
aktivSor.Elso(i,f.azonosito);
      pf.MelyFolyamat(f,j{nem fontos});
    End{PFolyamatSor.Elso};

 

    Function PFolyamat.SorHossz:Integer;
    Begin
     
SorHossz:=aktivSor.SorHossz
    End{PFolyamat.SorHossz};

 

{
******* história-típus ****************************************************
                                                                          *
}

  Var
    
h : Text;          {egy sora: T:4+':'+azonosito:10+'='+allapot:4}

  Const
    
fnev = 'folyamat'; {história-file "vezetékneve"}

     Procedure FileNyit;
       Begin
        
Assign(h,fnev+'.hst'); ReWrite(h);
         Writeln(h,' Idö        Autó          Allapot');
       End{FileNyit};

     Procedure Rogzit(pf:PFolyamat);
       Var
         sor,s1,s2: String;
         i : Byte;
       Begin
         Str(pf.T:4,sor); Writeln(h,sor);
         {Nyomkövetés a képernyőn is:}
         Writeln(pf.T:4);
         For i:=1 to oUt do
         Begin
           sor:='   ';
           Str(ok[i].azonosito:10,s1); Str(ok[i].allapot:4,s2);
           sor:=sor+':'+s1+' ('+AzonToString(ok[i].azonosito)+')'
                +'='+s2+' ('+SAllapot[ok[i].allapot]+')';
           Writeln(h,sor);

           {Nyomkövetés a képernyőn is:}
           If ok[ig].allapot=3{kereszteződésben} then HighVideo;
           Writeln(ok[ig].azonosito:6,'-s ('+
                   AzonToString(ok[ig].azonosito)+') autó a(z) ',
                   ok[ig].allapot,'. lépést ('+
                   SAllapot[ok[ig].allapot],') hajtja végre.');
           If ok[ig].allapot=3{kereszteződésben} then NormVideo;
         End;
       End{Rogzit};

     Procedure FileZar;
       Begin
         Close(h);
       End{FileZar};

{                                                                         *
******* história-típus ****************************************************
}

 

Begin
  ClrScr;
  FileNyit; {história-file nyitás}
  pf.inic; s.inic;
  P:=0.5; SzulVarSzam:=1;
  pf.T:=1;
  For i:=1 to SzulVarSzam+2 do If Random<P then pf.FolyamatSzul;
  Rogzit(pf); {história-fileba írás}
  c:=' ';

  While ((pf.SorHossz>0) or (s.SorHossz>0)) and (c<>Esc) do
  Begin
  
{az aktív folyamatok szimulációja:}
    For i:=1 to pf.Sorhossz do
    Begin
     
pf.Sorbol(t,f);
      f.keret;  {egyedi folyamat-szimuláció}
      If pf.FolyamatValtozott(f,j) then
      Begin
       
pf.FolyamatModosit(f,j); pf.Sorba(t,f);
      End;

     {Történt-e változás a szemaforok körül?
      Az inaktív -a várakozási sor(ok)ban álló- folyamatok szimulációja
      (azaz minden szemaforra):}
      If s.SorHossz>0 then
      Begin
       
s.Q(f);
        If f.azonosito<>UresFolyamat.azonosito then
        Begin
        
{továbblép:}
          pf.MelyFolyamat(f,j);
          f.keret;
          pf.FolyamatModosit(f,j); pf.Sorba(T,f)
        End;
      End;
    End;

   {a végállapotba jutott folyamatok kihagyása:}
    For i:=1 to pf.SorHossz do
    Begin
     
pf.Sorbol(t,f); pf.MelyFolyamat(f,j);
      If f.allapot=VegAllapot then pf.FolyamatTemet(j)
                              else pf.Sorba(t,f);
    End;

   {új folyamatok beléptetése:}
    For i:=1 to SzulVarSzam do If Random<P then pf.FolyamatSzul;
   {múlik az idô:}
    Inc(pf.T);
    Rogzit(pf); {história-fileba írás}
    c:=ReadKey;
  End;
End.

A história-file

… a KERESZT2.EXE demó futás után…:

 

 Idő        Autó          Állapot

   1

   :         1 (K->Ny)=   1 (előtt)

   :         2 (K->Ny)=   1 (előtt)

   :        -3 (Ny->K)=   1 (előtt)

   2

   :         1 (K->Ny)=   2 (P)

   :         2 (K->Ny)=   2 (P)

   :        -3 (Ny->K)=   2 (P)

   :        -4 (Ny->K)=   1 (előtt)

   3

   :         1 (K->Ny)=   3 (ben)

   :         2 (K->Ny)=   2 (P)

   :        -3 (Ny->K)=   2 (P)

   :        -4 (Ny->K)=   2 (P)

   :      -205 (Ny->D)=   1 (előtt)

   4

   :         1 (K->Ny)=   4 (V)

   :         2 (K->Ny)=   3 (ben)

   :        -3 (Ny->K)=   2 (P)

   :        -4 (Ny->K)=   2 (P)

   :      -205 (Ny->D)=   2 (P)

   :      -206 (Ny->D)=   1 (előtt)

   5

   :         1 (K->Ny)=   5 (után)

   :         2 (K->Ny)=   4 (V)

   :        -3 (Ny->K)=   3 (ben)

   :        -4 (Ny->K)=   2 (P)

   :      -205 (Ny->D)=   2 (P)

   :      -206 (Ny->D)=   2 (P)

   6

   :         2 (K->Ny)=   5 (után)

   :        -3 (Ny->K)=   4 (V)

   :        -4 (Ny->K)=   3 (ben)

   :      -205 (Ny->D)=   2 (P)

   :      -206 (Ny->D)=   2 (P)

   :       207 (K-> D)=   1 (előtt)

   7

   :        -3 (Ny->K)=   5 (után)

   :        -4 (Ny->K)=   4 (V)

   :      -205 (Ny->D)=   3 (ben)

   :      -206 (Ny->D)=   2 (P)

   :       207 (K-> D)=   2 (P)

   8

   :        -4 (Ny->K)=   5 (után)

   :      -205 (Ny->D)=   4 (V)

   :      -206 (Ny->D)=   3 (ben)

   :       207 (K-> D)=   2 (P)

   :        -8 (Ny->K)=   1 (előtt)

   9

   :      -205 (Ny->D)=   5 (után)

   :      -206 (Ny->D)=   4 (V)

   :       207 (K-> D)=   3 (ben)

   :        -8 (Ny->K)=   2 (P)

   :         9 (K->Ny)=   1 (előtt)

  10

   :      -206 (Ny->D)=   5 (után)

   :       207 (K-> D)=   4 (V)

   :        -8 (Ny->K)=   3 (ben)

   :         9 (K->Ny)=   2 (P)

   :      -110 (Ny->É)=   1 (előtt)

  11

   :       207 (K-> D)=   5 (után)

   :        -8 (Ny->K)=   4 (V)

   :         9 (K->Ny)=   3 (ben)

   :      -110 (Ny->É)=   2 (P)

  12

   :        -8 (Ny->K)=   5 (után)

   :         9 (K->Ny)=   4 (V)

   :      -110 (Ny->É)=   3 (ben)

   :       211 (K-> D)=   1 (előtt)

  13

   :         9 (K->Ny)=   5 (után)

   :      -110 (Ny->É)=   4 (V)

   :       211 (K-> D)=   2 (P)

   :       212 (K-> D)=   1 (előtt)

  14

   :      -110 (Ny->É)=   5 (után)

   :       211 (K-> D)=   3 (ben)

   :       212 (K-> D)=   2 (P)

   :       -13 (Ny->K)=   1 (előtt)

  15

   :       211 (K-> D)=   4 (V)

   :       212 (K-> D)=   3 (ben)

   :       -13 (Ny->K)=   2 (P)

  16

   :       211 (K-> D)=   5 (után)

   :       212 (K-> D)=   4 (V)

   :       -13 (Ny->K)=   3 (ben)

   :      -114 (Ny->É)=   1 (előtt)

  17

   :       212 (K-> D)=   5 (után)

   :       -13 (Ny->K)=   4 (V)

   :      -114 (Ny->É)=   2 (P)

  18

   :       -13 (Ny->K)=   5 (után)

   :      -114 (Ny->É)=   3 (ben)

  19

   :      -114 (Ny->É)=   4 (V)

  20

   :      -114 (Ny->É)=   5 (után)

  21