Skip to content

Instantly share code, notes, and snippets.

@ndyakov
Last active August 29, 2015 14:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ndyakov/e702ad3e9a9ed8371506 to your computer and use it in GitHub Desktop.
Save ndyakov/e702ad3e9a9ed8371506 to your computer and use it in GitHub Desktop.
Sleeping Barber Problem
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