Created
April 7, 2012 21:56
-
-
Save jordanorelli/2332384 to your computer and use it in GitHub Desktop.
dining philosophers
This file contains hidden or 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" | |
"sync" | |
"time" | |
) | |
type Philosopher struct { | |
Id int | |
Left *Fork | |
Right *Fork | |
} | |
type Fork struct { | |
sync.Mutex | |
Id int | |
} | |
func Seat(numPhilosophers int) []*Philosopher { | |
zeroFork := &Fork{Id: 0} | |
prevFork := zeroFork | |
philosophers := []*Philosopher{} | |
for i := 0; i < numPhilosophers - 1; i++ { | |
thisFork := &Fork{Id: i + 1} | |
philosophers = append(philosophers, &Philosopher{Id: i, Left: prevFork, Right: thisFork}) | |
prevFork = thisFork | |
} | |
philosophers = append(philosophers, &Philosopher{Id: numPhilosophers - 1, Left: prevFork, Right: zeroFork}) | |
philosophers[0].Left, philosophers[0].Right = philosophers[0].Right, philosophers[0].Left | |
return philosophers | |
} | |
func (phil *Philosopher) Eat(eating, thinking chan int) { | |
for { | |
phil.Right.Lock() | |
time.Sleep(time.Duration(rand.Int63n(1e7))) | |
phil.Left.Lock() | |
eating <- phil.Id | |
time.Sleep(time.Duration(rand.Int63n(1e8))) | |
phil.Right.Unlock() | |
time.Sleep(time.Duration(rand.Int63n(1e7))) | |
phil.Left.Unlock() | |
thinking <- phil.Id | |
time.Sleep(time.Duration(rand.Int63n(1e8))) | |
} | |
} | |
func (phil *Philosopher) String() string { | |
return fmt.Sprintf("[Philosopher: Id: %d, Left: %d, Right: %d]", phil.Id, phil.Left.Id, phil.Right.Id) | |
} | |
func printStatus(thinkCount []int, eatCount []int, mu *sync.Mutex) { | |
mu.Lock() | |
for i, val := range thinkCount { | |
fmt.Print("(", val, ",", eatCount[i], ")", "\t") | |
} | |
fmt.Print("\n") | |
mu.Unlock() | |
} | |
func main() { | |
numPhilosophers := 20 | |
philosophers := Seat(numPhilosophers) | |
for _, phil := range philosophers { | |
fmt.Println(phil) | |
} | |
eating := make(chan int) | |
thinking := make(chan int) | |
for _, phil := range philosophers { | |
go phil.Eat(eating, thinking) | |
} | |
eatCount, thinkCount := make([]int, numPhilosophers), make([]int, numPhilosophers) | |
writeLock := new(sync.Mutex) | |
go func() { | |
for id := range eating { | |
eatCount[id]++ | |
printStatus(thinkCount, eatCount, writeLock) | |
} | |
}() | |
for id := range thinking { | |
thinkCount[id]++ | |
printStatus(thinkCount, eatCount, writeLock) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment