Skip to content

Instantly share code, notes, and snippets.

@caelifer
Last active March 7, 2017 04:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caelifer/7f3764756f11e5e3cec5 to your computer and use it in GitHub Desktop.
Save caelifer/7f3764756f11e5e3cec5 to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"math/rand"
"time"
)
type Fork struct{}
type Thinker struct {
Name string
Forks [2]chan *Fork
}
func (t Thinker) Start() {
go func() {
for {
t.Think()
t.Eat()
}
}()
}
func (t Thinker) Think() {
fmt.Printf("thinker %s is thinking...\n", t.Name)
time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond)
}
func (t Thinker) Eat() {
fmt.Printf("thinker %s is ready to eat...\n", t.Name)
var left, right *Fork
var ok bool
for {
forkIdxLeft := rand.Intn(2)
forkIdxRight := (forkIdxLeft + 1) % 2
// Get first fork
if left, ok = t.GetFork(forkIdxLeft); ok {
// Get second fork
if right, ok = t.GetFork(forkIdxRight); ok {
fmt.Printf("thinker %s is eating!\n", t.Name)
time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
// Put both forks back
t.Forks[0] <- left
t.Forks[1] <- right
fmt.Printf("thinker %s finished eating\n", t.Name)
break // Exit loop here
} else {
// Put first fork back and complain
fmt.Printf("thinker %s putting the fork back because the other is not available\n", t.Name)
t.Forks[forkIdxLeft] <- left
}
}
fmt.Printf("thinker %s is hungerly awaiting for the forks...\n", t.Name)
time.Sleep(time.Duration(rand.Intn(10)) * time.Millisecond)
}
}
func (t Thinker) GetFork(idx int) (*Fork, bool) {
side := "right"
if idx&0x1 == 0 {
side = "left"
}
fmt.Printf("thinker %s is reaching for the %s fork\n", t.Name, side)
var fork *Fork
select {
case fork = <-t.Forks[idx]:
default:
fmt.Printf("thinker %s is blocked\n", t.Name)
return nil, false
}
return fork, true
}
var thinkers = []Thinker{
{Name: "#1"},
{Name: "#2"},
{Name: "#3"},
}
func init() {
// Seed our random generator
rand.Seed(time.Now().Unix())
// Give thinkers forks
n := len(thinkers)
for i := 0; i < n; i++ {
thinkers[i].Forks[0] = addFork()
if i > 0 {
thinkers[i].Forks[1] = thinkers[i-1].Forks[0]
}
}
thinkers[0].Forks[1] = thinkers[n-1].Forks[0] // Last fork goes between first and nth thinkers
// Animate them
for _, t := range thinkers {
t.Start()
}
}
func addFork() chan *Fork {
f := make(chan *Fork, 1)
f <- &Fork{}
return f
}
func main() {
time.Sleep(2 * time.Second)
fmt.Println("Exiting simulation")
}
@caelifer
Copy link
Author

caelifer commented Aug 24, 2015

Live code - https://play.golang.org/p/Nz2bDvNmHG

Output:

thinker #1 is thinking...
thinker #2 is thinking...
thinker #3 is thinking...
thinker #2 is ready to eat...
thinker #2 is reaching for the left fork
thinker #2 is reaching for the right fork
thinker #2 is eating!
thinker #2 finished eating
thinker #2 is thinking...
thinker #1 is ready to eat...
thinker #1 is reaching for the right fork
thinker #1 is reaching for the left fork
thinker #1 is eating!
thinker #2 is ready to eat...
thinker #2 is reaching for the right fork
thinker #2 is blocked
thinker #2 is hungerly awaiting for the forks...
thinker #2 is reaching for the left fork
thinker #2 is reaching for the right fork
thinker #2 is blocked
thinker #2 putting the fork back because the other is not available
thinker #2 is hungerly awaiting for the forks...
thinker #2 is reaching for the right fork
thinker #2 is blocked
thinker #2 is hungerly awaiting for the forks...
thinker #2 is reaching for the left fork
thinker #2 is reaching for the right fork
thinker #2 is blocked
thinker #2 putting the fork back because the other is not available
thinker #2 is hungerly awaiting for the forks...
thinker #1 finished eating
thinker #1 is thinking...
thinker #2 is reaching for the right fork
thinker #2 is reaching for the left fork
thinker #2 is eating!
thinker #2 finished eating
thinker #2 is thinking...
thinker #3 is ready to eat...
thinker #3 is reaching for the left fork
thinker #3 is reaching for the right fork
thinker #3 is eating!
thinker #1 is ready to eat...
thinker #1 is reaching for the right fork
thinker #1 is blocked
thinker #1 is hungerly awaiting for the forks...
thinker #1 is reaching for the left fork
thinker #1 is reaching for the right fork
thinker #1 is blocked
thinker #1 putting the fork back because the other is not available
thinker #1 is hungerly awaiting for the forks...
thinker #1 is reaching for the right fork
thinker #1 is blocked
thinker #1 is hungerly awaiting for the forks...
thinker #1 is reaching for the right fork
thinker #1 is blocked
thinker #1 is hungerly awaiting for the forks...
thinker #1 is reaching for the left fork
thinker #1 is reaching for the right fork
thinker #1 is blocked
thinker #1 putting the fork back because the other is not available
thinker #1 is hungerly awaiting for the forks...
thinker #3 finished eating
thinker #3 is thinking...
thinker #1 is reaching for the left fork
thinker #1 is reaching for the right fork
thinker #1 is eating!
thinker #2 is ready to eat...
thinker #2 is reaching for the left fork
thinker #2 is reaching for the right fork
thinker #2 is blocked
thinker #2 putting the fork back because the other is not available
thinker #2 is hungerly awaiting for the forks...
thinker #2 is reaching for the right fork
thinker #2 is blocked
thinker #2 is hungerly awaiting for the forks...
thinker #2 is reaching for the left fork
thinker #2 is reaching for the right fork
thinker #2 is blocked
thinker #2 putting the fork back because the other is not available
thinker #2 is hungerly awaiting for the forks...
thinker #2 is reaching for the left fork
thinker #2 is reaching for the right fork
thinker #2 is blocked
thinker #2 putting the fork back because the other is not available
thinker #2 is hungerly awaiting for the forks...
thinker #1 finished eating
thinker #1 is thinking...
thinker #2 is reaching for the left fork
thinker #2 is reaching for the right fork
thinker #2 is eating!
thinker #2 finished eating
thinker #2 is thinking...
thinker #1 is ready to eat...
thinker #1 is reaching for the left fork
thinker #1 is reaching for the right fork
thinker #1 is eating!
thinker #1 finished eating
thinker #1 is thinking...
thinker #3 is ready to eat...
thinker #3 is reaching for the right fork
thinker #3 is reaching for the left fork
thinker #3 is eating!
thinker #3 finished eating
thinker #3 is thinking...
thinker #2 is ready to eat...
thinker #2 is reaching for the left fork
thinker #2 is reaching for the right fork
thinker #2 is eating!
thinker #2 finished eating
thinker #2 is thinking...
thinker #1 is ready to eat...
thinker #1 is reaching for the right fork
thinker #1 is reaching for the left fork
thinker #1 is eating!
thinker #1 finished eating
thinker #1 is thinking...
thinker #3 is ready to eat...
thinker #3 is reaching for the left fork
thinker #3 is reaching for the right fork
thinker #3 is eating!
thinker #3 finished eating
thinker #3 is thinking...
thinker #1 is ready to eat...
thinker #1 is reaching for the right fork
thinker #1 is reaching for the left fork
thinker #1 is eating!
thinker #1 finished eating
thinker #1 is thinking...
thinker #2 is ready to eat...
thinker #2 is reaching for the right fork
thinker #2 is reaching for the left fork
thinker #2 is eating!
thinker #2 finished eating
thinker #2 is thinking...
thinker #3 is ready to eat...
thinker #3 is reaching for the right fork
thinker #3 is reaching for the left fork
thinker #3 is eating!
thinker #1 is ready to eat...
thinker #1 is reaching for the right fork
thinker #1 is blocked
thinker #1 is hungerly awaiting for the forks...
thinker #3 finished eating
thinker #3 is thinking...
thinker #1 is reaching for the right fork
thinker #1 is reaching for the left fork
thinker #1 is eating!
thinker #1 finished eating
thinker #1 is thinking...
thinker #3 is ready to eat...
thinker #3 is reaching for the right fork
thinker #3 is reaching for the left fork
thinker #3 is eating!
thinker #3 finished eating
thinker #3 is thinking...
thinker #2 is ready to eat...
thinker #2 is reaching for the right fork
thinker #2 is reaching for the left fork
thinker #2 is eating!
thinker #2 finished eating
thinker #2 is thinking...
thinker #1 is ready to eat...
thinker #1 is reaching for the right fork
thinker #1 is reaching for the left fork
thinker #1 is eating!
thinker #1 finished eating
thinker #1 is thinking...
Exiting simulation

Program exited.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment