Exemplos para Monitor e Rendezvous

Monitor

Exemplos de uso de Monitores em LI2:

{
    var a = 0, 
    proc incA ()  {
        synch( a ) {
            a := a + 1;
            write("parou");
            wait( a );
            write("continuou");
            a := a + 1
        }
    };

    call incA()
    par
    synch( a ) {
        a := a + 2;
        notify( a )
    }
}
{ 
    var a  =  0, 
    proc incA () {
        synch( a ) {
            a := a + 1
        };
        write( a );
        write(" ")
    },
    proc incB () {
        synch( a ) {
            a := a + a
        };
        write( a );
        write(" ")
    };

    call incA()
    par
    call incB()
}

Rendezvous

Exemplos do uso de Rendezvous:

{
    entry sync() {
        skip
    };

    {
        var y = 5;
        {
            accept sync;
            write(y);
        }
    }
    par
    {
        var x = 0;
        {
            write(x);
            callEntry sync();
        }
    }    
}

// Declaracao das variaveis globais
// (nao faz nada)
// ...
// .
// Bloco da primeira task
// Declaracao de suas variaveis locais
// ...
// Ponto de sincronizacao
// ...
// ...
// .
// Task1 paralela a Task2
// ...
// .
// .
// Escreve o x
// Se reune com a Task1
// .
// Fim da Task2
// Fim do Programa
{
    var dobro = 0,
    
    entry produza()
    {
        dobro := dobro + dobro
    };

    {
        var i = 0;
        {
            while ( not i == 11 ) do
            {
                accept produza;
                i := i + 1;
            };
        }
    }
    par
    {
        var i = 0;
        {
            while ( not i == 11 ) do
            {
                dobro := i;
                write("Dobro de "); write(i); write(": ");
                callEntry produza();
                write(dobro); write(" || ");
                i := i + 1;
            };
        }
    }
}

 

{
    var i = 1,

    entry sync1() {
        skip
    },

    entry sync2() {
        skip
    },

    entry sync3() {
        skip
    };

    {
        var y = 5;
        {
            while ( not i == 0 ) do
            {
                accept sync1;
                write("task2");
                callEntry sync3();
            };
        }
    }
    par
    {
        var x = 0;
        {
            while ( not i == 0 ) do
            {
                accept sync2;
                write("task1|");
                callEntry sync1();
            };
        }
    }
    par
    {
        while ( not i == 0 ) do
        {
            write("i: ");
            write(i);
            write("-");
            callEntry sync2();
            i := i + 1;
            accept sync3;
            write(" || ");
        };
    }
}

Observe o mesmo exemplo acima SEM o uso de Rendezvous e perceba que a seqüência das tarefas que são executadas é completamente aleatória.

{
    var i = 1;

    {
        var y = 5;
        {
            while ( not i == 0 ) do
            {
                write("task2");
            };
        }
    }
    par
    {
        var x = 0;
        {
            while ( not i == 0 ) do
            {
                write("task1|");
            };
        }
    }
    par
    {
        while ( not i == 0 ) do
        {
            write("i: ");
            write(i);
            write("-");
            i := i + 1;
            write(" || ");
        };
    }
}
Exemplo 3 SEM Rendezvous

 

Escopo Negativo

Os exemplos listados abaixo não deveriam funcionar. Para cada um, existe uma justificativa e explicação.