Skip to content

Instantly share code, notes, and snippets.

@ymakino
Last active May 11, 2023 10:16
Show Gist options
  • Save ymakino/259257d10a7051a750886a713d16f281 to your computer and use it in GitHub Desktop.
Save ymakino/259257d10a7051a750886a713d16f281 to your computer and use it in GitHub Desktop.
An implementation of the dining philosophers problem in Go.
package main
import (
"fmt"
"time"
"math/rand"
)
var msg = &struct{}{}
const N = 5
var Id [N]int
var start [N]chan any
var finish [N]chan any
var get [N][N]chan any
var put [N][N]chan any
func initialize() {
for i:=0; i<N; i++ {
Id[i] = i
}
for i:=0; i<N; i++ {
start[i] = make(chan any)
finish[i] = make(chan any)
}
for i:=0; i<N; i++ {
for j:=0; j<N; j++ {
get[i][j] = make(chan any)
put[i][j] = make(chan any)
}
}
}
func inc(i int) int {
return (i+1)%N
}
func dec(i int) int {
return (i-1+N)%N
}
func Phil(i int) {
sync := make(chan any)
getFork := func(num int) { get[i][num] <- msg; fmt.Printf(" Phil(%d) get Fork(%d)\n", i, num); sync <- msg }
putFork := func(num int) { put[i][num] <- msg; fmt.Printf(" Phil(%d) put Fork(%d)\n", i, num); sync <- msg }
for {
<-start[i]
fmt.Printf("Start: Phil(%d)\n", i)
go getFork(i); go getFork(inc(i)); <-sync; <-sync;
go putFork(i); go putFork(inc(i)); <-sync; <-sync;
fmt.Printf("Finish: Phil(%d)\n", i)
finish[i] <- msg
}
}
func Fork(i int) {
for {
select {
case <-get[dec(i)][i]: <-put[dec(i)][i]
case <-get[i][i]: <-put[i][i]
}
}
}
func Phils() {
for _, num := range Id {
go Phil(num)
}
}
func Forks() {
for _, num := range Id {
go Fork(num)
}
}
func DiningPhil() {
go Phils()
go Forks()
}
func run() {
seed := time.Now().UnixNano()
fmt.Printf("Seed: %d\n", seed);
rand.Seed(seed)
for {
num := rand.Intn(N)
start[num] <- msg
go func(num int) { <-finish[num] }(num)
}
}
func main() {
initialize()
go DiningPhil()
run()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment