Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Alberto Zirondelli soluzione dell'esame
- package main
- import (
- "flag"
- "log"
- "math/rand"
- "os"
- "time"
- )
- const (
- MAXBUFF = 100 //max channel buffer
- MAXARTICOLICHEPUOCHIEDERE = 10 //max numero processi
- MAX = 30 //numero massimo di elementi che può consegnare in una volta un fornitore e che possono starci in magazzino
- //gli articoli serviti
- MARTELLO = 0
- TENAGLIA = 1
- BADILE = 2
- )
- var (
- Info *log.Logger
- )
- func sleepRand() {
- tt := rand.Intn(5) + 1 //Random globale è thread safe
- time.Sleep(time.Duration(tt) * time.Second)
- }
- func when(b bool, c <-chan *Richiesta) <-chan *Richiesta {
- if !b {
- return nil
- }
- return c
- }
- type Richiesta struct {
- idRichiedente int //chi l'ha richiesto
- tipo int //il tipo di attrezzo
- numero int //il numero di elementi (se negativo vuol dire che li vuole prelevare)
- CanaleDiChiamata chan bool //Canale usato per comunicare al cliente/fornitore che quello che ha chiesto è pronto
- }
- func newRichiesta(idRichiedente int, tipo int, numero int) {
- return &Richiesta{
- idRichiedente, tipo, numero, make(chan bool),
- }
- }
- func fornitore(int id, int articolo, codaMagazzino chan<- *Richiesta) {
- Info.println("[Fornitore %d] Creato\n", id)
- for {
- sleepRand()
- r := newRichiesta(id, articolo, rand.Intn(MAX+1))
- Info.println("[Fornitore %d] Ho creato un lotto di %d grande %d\n", id, articolo, r.numero)
- codaMagazzino <- r
- Info.println("[Fornitore %d] Ho consegnato un'altro lotto di %d\n", id, articolo)
- } //for
- } //server
- func clientePrivato(int id, codaMagazzino chan<- *Richiesta) {
- Info.println("[ClientePrivato %d] Creato\n", id)
- for {
- sleepRand()
- r := newRichiesta(id, rand.Intn(3), -1) //ne possono chiedere uno alla volta di un tipo qualunque
- Info.println("[ClientePrivato %d] VOGLIO UN %d\n", id, r.tipo)
- codaMagazzino <- creaRichiestaRandom()
- Info.println("[ClientePrivato %d] Ho ottenuto quel che volevo, grazie buon uomo!\n", id)
- }
- } //cliente privato
- func clienteNegoziante(int id, codaMagazzino chan<- *Richiesta) {
- Info.println("[clienteNegoziante %d] Creato\n", id)
- for {
- sleepRand()
- 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
- //comunque metto un vincolo per evitare che mi impalli il programmino con 10000 richieste
- Info.println("[clienteNegoziante %d] VOGLIO UN %d in quantità %d\n", id, r.tipo, r.numero)
- codaMagazzino <- creaRichiestaRandom()
- Info.println("[clienteNegoziante %d] Ho ottenuto quel che volevo, grazie buon uomo!\n", id)
- }
- } //cliente negoziante
- func gestoreMagazzino(codaClienti <-chan *Richiesta, codaFornitori <-chan *Richiesta) {
- //inizialmente non ci sono spettatori nello stadio, tutti gli operatori sono in servizio
- ContatoreMagazzino := map[int]int{
- MARTELLO: MAX,
- TENAGLIA: MAX,
- BADILE: MAX,
- }
- //due canali di dimensione 1 per metterci quelli che stanno venendo serviti in questo momento
- canaleDiAttesaFornitori, canaleDiAttesaClienti := make(chan *Richiesta, 1), make(chan *Richiesta, 1)
- for {
- select {
- case richiesta := <-when(condizioneCliente, codaClienti):
- Info.Printf("[Gestore]\tCliente %d è stato chiamato al bancone\n", richiesta.idRichiedente)
- canaleDiAttesaClienti <- richiesta // chiama lo spettatore al controllo
- case richiesta := <-canaleDiAttesaClienti:
- //qua viene veramente prelevato
- Info.Printf("[Gestore]\ttCliente %d sta venendo servito\n", richiesta.idRichiedente)
- if ContatoreMagazzino[richiesta.tipo] > richiesta.numero {
- //ce ne sono a sufficienza
- ContatoreMagazzino[richiesta.tipo] = ContatoreMagazzino[richiesta.tipo] - richiesta.numero
- //è stato servito il cliente
- richiesta.CanaleDiChiamata <- true //ha finito
- } else {
- //non ce ne sono abbastanza
- richiesta.numero = richiesta.numero - ContatoreMagazzino[richiesta.tipo]
- ContatoreMagazzino[richiesta.tipo] = 0
- //lo rimetto in attesa
- richiesta <- richiesta
- }
- // ---- qua c'è la parte per il fornitore, simile a quella sopra
- } //select
- } //for
- } //server
- func init() {
- rand.Seed(time.Now().Unix())
- Info = log.New(os.Stdout, "INFO: ", log.Ltime|log.Lshortfile)
- }
- func main() {
- pSpettatori := flag.Int("spettatori", 16, "Numero di spettatori")
- flag.Parse()
- NSpettatori := *pSpettatori
- codafornitore := make(chan int)
- codaControlliOspiti, codaControlliLocali, end := make(chan *Spettatore), make(chan *Spettatore), make(chan bool)
- //Go routine server
- go fornitore(codafornitore, end)
- go varcoDiAccesso(codaControlliOspiti, codaControlliLocali, end)
- //Go routine client
- for i := 0; i < NSpettatori; i++ {
- go newSpettatore(i).FaiCioCheDeviFare(codafornitore, codaControlliOspiti, codaControlliLocali)
- }
- //attesa che tutti gli spettatori siano entrati allo stadio
- for i := 0; i < NSpettatori; i++ {
- <-done
- }
- end <- true //chiudi fornitore
- end <- true //chiudi controlli
- <-done //attendi chiusura fornitore
- <-done //attendi chiusura controlli
- //che la partita abbia inizio
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement