Advertisement
Guest User

Untitled

a guest
Jan 18th, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.15 KB | None | 0 0
  1. // Alberto Zirondelli soluzione dell'esame
  2. package main
  3.  
  4. import (
  5. "flag"
  6. "log"
  7. "math/rand"
  8. "os"
  9. "time"
  10. )
  11.  
  12. const (
  13. MAXBUFF = 100 //max channel buffer
  14. MAXARTICOLICHEPUOCHIEDERE = 10 //max numero processi
  15. MAX = 30 //numero massimo di elementi che può consegnare in una volta un fornitore e che possono starci in magazzino
  16.  
  17. //gli articoli serviti
  18. MARTELLO = 0
  19. TENAGLIA = 1
  20. BADILE = 2
  21. )
  22.  
  23. var (
  24. Info *log.Logger
  25. )
  26.  
  27. func sleepRand() {
  28. tt := rand.Intn(5) + 1 //Random globale è thread safe
  29. time.Sleep(time.Duration(tt) * time.Second)
  30. }
  31.  
  32. func when(b bool, c <-chan *Richiesta) <-chan *Richiesta {
  33. if !b {
  34. return nil
  35. }
  36. return c
  37. }
  38.  
  39. type Richiesta struct {
  40. idRichiedente int //chi l'ha richiesto
  41. tipo int //il tipo di attrezzo
  42. numero int //il numero di elementi (se negativo vuol dire che li vuole prelevare)
  43. CanaleDiChiamata chan bool //Canale usato per comunicare al cliente/fornitore che quello che ha chiesto è pronto
  44. }
  45.  
  46. func newRichiesta(idRichiedente int, tipo int, numero int) {
  47. return &Richiesta{
  48. idRichiedente, tipo, numero, make(chan bool),
  49. }
  50. }
  51.  
  52. func fornitore(int id, int articolo, codaMagazzino chan<- *Richiesta) {
  53. Info.println("[Fornitore %d] Creato\n", id)
  54. for {
  55. sleepRand()
  56. r := newRichiesta(id, articolo, rand.Intn(MAX+1))
  57. Info.println("[Fornitore %d] Ho creato un lotto di %d grande %d\n", id, articolo, r.numero)
  58. codaMagazzino <- r
  59. Info.println("[Fornitore %d] Ho consegnato un'altro lotto di %d\n", id, articolo)
  60. } //for
  61.  
  62. } //server
  63.  
  64. func clientePrivato(int id, codaMagazzino chan<- *Richiesta) {
  65. Info.println("[ClientePrivato %d] Creato\n", id)
  66. for {
  67. sleepRand()
  68. r := newRichiesta(id, rand.Intn(3), -1) //ne possono chiedere uno alla volta di un tipo qualunque
  69. Info.println("[ClientePrivato %d] VOGLIO UN %d\n", id, r.tipo)
  70. codaMagazzino <- creaRichiestaRandom()
  71. Info.println("[ClientePrivato %d] Ho ottenuto quel che volevo, grazie buon uomo!\n", id)
  72. }
  73. } //cliente privato
  74.  
  75. func clienteNegoziante(int id, codaMagazzino chan<- *Richiesta) {
  76. Info.println("[clienteNegoziante %d] Creato\n", id)
  77. for {
  78. sleepRand()
  79. r := newRichiesta(id, rand.Intn(3), -rand.Intn(MAXARTICOLICHEPUOCHIEDERE-K)+K) //ne posso chiedere di un tipo K quanti ne voglio, basta che siano più di K
  80. //comunque metto un vincolo per evitare che mi impalli il programmino con 10000 richieste
  81. Info.println("[clienteNegoziante %d] VOGLIO UN %d in quantità %d\n", id, r.tipo, r.numero)
  82. codaMagazzino <- creaRichiestaRandom()
  83. Info.println("[clienteNegoziante %d] Ho ottenuto quel che volevo, grazie buon uomo!\n", id)
  84. }
  85. } //cliente negoziante
  86.  
  87. func gestoreMagazzino(codaClienti <-chan *Richiesta, codaFornitori <-chan *Richiesta) {
  88. //inizialmente non ci sono spettatori nello stadio, tutti gli operatori sono in servizio
  89. ContatoreMagazzino := map[int]int{
  90. MARTELLO: MAX,
  91. TENAGLIA: MAX,
  92. BADILE: MAX,
  93. }
  94.  
  95. //due canali di dimensione 1 per metterci quelli che stanno venendo serviti in questo momento
  96. canaleDiAttesaFornitori, canaleDiAttesaClienti := make(chan *Richiesta, 1), make(chan *Richiesta, 1)
  97.  
  98. for {
  99. select {
  100. case richiesta := <-when(condizioneCliente, codaClienti):
  101. Info.Printf("[Gestore]\tCliente %d è stato chiamato al bancone\n", richiesta.idRichiedente)
  102. canaleDiAttesaClienti <- richiesta // chiama lo spettatore al controllo
  103. case richiesta := <-canaleDiAttesaClienti:
  104. //qua viene veramente prelevato
  105. Info.Printf("[Gestore]\ttCliente %d sta venendo servito\n", richiesta.idRichiedente)
  106. if ContatoreMagazzino[richiesta.tipo] > richiesta.numero {
  107. //ce ne sono a sufficienza
  108. ContatoreMagazzino[richiesta.tipo] = ContatoreMagazzino[richiesta.tipo] - richiesta.numero
  109. //è stato servito il cliente
  110. richiesta.CanaleDiChiamata <- true //ha finito
  111. } else {
  112. //non ce ne sono abbastanza
  113. richiesta.numero = richiesta.numero - ContatoreMagazzino[richiesta.tipo]
  114. ContatoreMagazzino[richiesta.tipo] = 0
  115. //lo rimetto in attesa
  116. richiesta <- richiesta
  117. }
  118.  
  119. // ---- qua c'è la parte per il fornitore, simile a quella sopra
  120. } //select
  121.  
  122. } //for
  123.  
  124. } //server
  125.  
  126. func init() {
  127. rand.Seed(time.Now().Unix())
  128. Info = log.New(os.Stdout, "INFO: ", log.Ltime|log.Lshortfile)
  129. }
  130.  
  131. func main() {
  132. pSpettatori := flag.Int("spettatori", 16, "Numero di spettatori")
  133. flag.Parse()
  134.  
  135. NSpettatori := *pSpettatori
  136.  
  137. codafornitore := make(chan int)
  138. codaControlliOspiti, codaControlliLocali, end := make(chan *Spettatore), make(chan *Spettatore), make(chan bool)
  139.  
  140. //Go routine server
  141. go fornitore(codafornitore, end)
  142. go varcoDiAccesso(codaControlliOspiti, codaControlliLocali, end)
  143.  
  144. //Go routine client
  145. for i := 0; i < NSpettatori; i++ {
  146. go newSpettatore(i).FaiCioCheDeviFare(codafornitore, codaControlliOspiti, codaControlliLocali)
  147. }
  148.  
  149. //attesa che tutti gli spettatori siano entrati allo stadio
  150. for i := 0; i < NSpettatori; i++ {
  151. <-done
  152. }
  153.  
  154. end <- true //chiudi fornitore
  155. end <- true //chiudi controlli
  156. <-done //attendi chiusura fornitore
  157. <-done //attendi chiusura controlli
  158. //che la partita abbia inizio
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement