Last active
August 29, 2015 14:09
-
-
Save ndyakov/e702ad3e9a9ed8371506 to your computer and use it in GitHub Desktop.
Sleeping Barber Problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math/rand" | |
"time" | |
) | |
type Barber struct { | |
Customer chan *Customer | |
WaitingRoom chan *Customer | |
Sleep chan struct{} | |
} | |
func NewBarber(waitingRoomSize int) *Barber { | |
b := &Barber{make(chan *Customer, 1), make(chan *Customer, waitingRoomSize), make(chan struct{}, 1)} | |
go b.Work() | |
return b | |
} | |
func (b *Barber) Work() { | |
b.Sleep <- struct{}{} | |
fmt.Println("[BARBER] Sleeping...zzZ") | |
for { | |
c := <-b.Customer | |
// There is a customer and the chair is empty. | |
b.CutHair(c) | |
select { | |
case c := <-b.WaitingRoom: | |
b.Customer <- c | |
fmt.Printf("[BARBER] Takes Customer #%d from the waiting room.\n", c.Number) | |
default: | |
// The Barber is sleeping. | |
b.Sleep <- struct{}{} | |
fmt.Println("[BARBER] Sleeping...zzZ") | |
} | |
} | |
} | |
func (b *Barber) CutHair(c *Customer) { | |
fmt.Printf("[BARBER] CutHair START: Customer #%d\n", c.Number) | |
time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond) | |
fmt.Printf("[BARBER] CutHair END: Customer #%d\n", c.Number) | |
} | |
type Customer struct { | |
Number int | |
} | |
func NewCustomer(number int) *Customer { | |
return &Customer{number} | |
} | |
func (c *Customer) WalkIn(b *Barber) { | |
fmt.Printf("[CUSTOMER] #%d walks in the shop\n", c.Number) | |
select { | |
case <-b.Sleep: | |
// If the barber is sleeping - wake him up. | |
b.Customer <- c | |
fmt.Printf("[CUSTOMER] #%d wakes up the barber\n", c.Number) | |
default: | |
// The barber is not sleeping - go to the waiting room. | |
select { | |
case b.WaitingRoom <- c: | |
// The is a place in the waiting room, sit on it. | |
fmt.Printf("[CUSTOMER] #%d sits in the waiting room\n", c.Number) | |
default: | |
// The is no place in the waiting room, leaving. | |
fmt.Printf("[CUSTOMER] #%d leaves the shop\n", c.Number) | |
} | |
} | |
} | |
func main() { | |
b := NewBarber(5) | |
for i := 0; i < 20; i++ { | |
c := NewCustomer(i) | |
time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond) | |
go c.WalkIn(b) | |
} | |
time.Sleep(2 * time.Second) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment