Forum Informatica Unict

LAUREA MAGISTRALE => Linguaggi di Programmazione, 9 CFU => Topic started by: lucacostantino on 11-06-2015, 17:49:50



Title: [PICT] Esercizio 22
Post by: lucacostantino on 11-06-2015, 17:49:50
Salve, stiamo avendo problemi a svolgere questo esercizio:

Scrivere un processo PICT che realizzi il meglio possibile il seguente oggetto OCaml
let mycell =
  object (self:'self)
  val mutable contents = 0
  method read = contents
  method write new_cont = contents <- new_cont
  method eq (c:`self) = (self#read=c#read)
  end;;
Mostrare se la soluzione puo' provocare eventuali problematiche di consistenza del contenuto in caso di chiamate parallele o sequenziali di metodi, ed eventualmente cambiare l'implementazione per risolverle.


Qualcuno è riuscito a farlo? Grazie mille  :-)|


Title: Re:[PICT] Esercizio 22
Post by: strikajici_fx on 16-06-2015, 16:54:25
Io l'ho fatto in questa maniera.
In pratica considero l'oggetto cell come un processo def, la variabile contents un canale in cui "conservo" il valore e read, write e eq sono processi def.
Code:
type cellType = [/[^Int] /[Int] /[cellType ^Bool]]

def cell r: ^cellType
   new contents: ^Int
   
   content!0
   | def read c:^Int =
         content?x = ( c!x | content!x)
   | def write val:Int =
         content?_ = content!val
   | def eq [other:cellType ^Bool] =
         other?[[r w e] b] =
              ( new c1:^Int
                new c2:^Int
                ( r!c1
                | c1?n1 =
                    ( read!c2
                    | c2?n2 =
                        ( if (== n1 n2)  //l'if l'ho scritto in maniera funzionale.
                            b!true
                          else
                            b!false
                        )
                    )
                )
              )
   | r![read write eq]

La seconda parte dell'esercizio però non l'ho ancora fatta, quindi bisognerebbe controllare se esistono eventuali problematiche in caso di chiamate parallele.
Credo che un problema esista almeno nel caso di scrittura e quindi una soluzione potrebbe essere sincronizzare il processo di scrittura.  .ciaociao


Title: Re:[PICT] Esercizio 22
Post by: lucacostantino on 16-06-2015, 18:57:12
Grazie della risposta! L'unica perplessità che mi sorge, per adesso, è che tu definisci dei processi col DEF senza usare la keyword AND.
Così facendo non c'è il rischio che il processo EQ non riesca a "vedere" i processi READ e WRITE (ripensando all'esempio del pingpong) al momento dell'invocazione?



Title: Re:[PICT] Esercizio 22
Post by: Franco Barbanera on 17-06-2015, 14:57:41
quindi bisognerebbe controllare se esistono eventuali problematiche in caso di chiamate parallele.

Ovvio che si.

FB


Title: Re:[PICT] Esercizio 22
Post by: Franco Barbanera on 17-06-2015, 14:58:05
Grazie della risposta! L'unica perplessità che mi sorge, per adesso, è che tu definisci dei processi col DEF senza usare la keyword AND.
Così facendo non c'è il rischio che il processo EQ non riesca a "vedere" i processi READ e WRITE (ripensando all'esempio del pingpong) al momento dell'invocazione?

Giusta osservazione.

FB


Title: Re:[PICT] Esercizio 22
Post by: strikajici_fx on 17-06-2015, 20:00:02
Grazie della risposta! L'unica perplessità che mi sorge, per adesso, è che tu definisci dei processi col DEF senza usare la keyword AND.
Così facendo non c'è il rischio che il processo EQ non riesca a "vedere" i processi READ e WRITE (ripensando all'esempio del pingpong) al momento dell'invocazione?

Ammetto che a questa cosa non ci avevo pensato  :-)| .
Con questi piccoli accorgimenti ho riscritto la soluzione

Code:
type cellType = [/[^Int] /[Int ^[ ]] /[cellType ^Bool]]

def cell r:^[cellType] =
( new content: ^Int
 new lock : ^[ ]

def read c:^Int =
         content?x = ( c!x | content!x)

and write [val:Int s:^[ ]] =
    lock?[ ] =
( content?_ = (content!val | lock![ ] | s![ ] ))

and eq [other:cellType ^Bool] =
         other?[[r w e] b] =
              ( new c1:^Int
                new c2:^Int
                ( r!c1
                | c1?n1 =
                    ( read!c2
                    | c2?n2 =
                        ( if (== n1 n2)  //l'if l'ho scritto in maniera funzionale.
                            b!true
                          else
                            b!false
                        )
                    )
                )
              )
run ( contents!0 | lock![ ] | r![read write eq] )
)

Ho aggiunto "run" che non avevo inserito e la sincronizzazione per il processo di scrittura. In questo modo non ci dovrebbero essere problemi se più processi vogliono modificare il valore content. Infatti se un processo sta già attuando la modifica, l'altro dovrà attendere che il segnale di sincronizzazione venga rilasciato. Per la "read" e per "eq" non dovrebbero esserci problemi (almeno per quanto riguarda il caso delle chiamate parallele).

Che ne dite, può andare? Attendo risposta  :-ciao