Skip to content

Instantly share code, notes, and snippets.

@abstractart
Last active January 29, 2022 20:08
Show Gist options
  • Save abstractart/94dc4f310ba1ed16bf83f40166c26ff2 to your computer and use it in GitHub Desktop.
Save abstractart/94dc4f310ba1ed16bf83f40166c26ff2 to your computer and use it in GitHub Desktop.
Dining philosopher problem solutions written in Go/Golang
package main
import (
"fmt"
"sync"
"time"
)
func main() {
count := 5
forks := make([]sync.Mutex, count)
var wg sync.WaitGroup
wg.Add(count)
for i := 0; i < count; i++ {
go philosoph(i, &forks[i], &forks[(i+1)%count])
}
wg.Wait()
}
func philosoph(i int, leftFork *sync.Mutex, rightFork *sync.Mutex) {
for {
fmt.Printf("Philosopher %d thinking\n", i)
time.Sleep(time.Second)
// one group of philosophers starts with left fork
if i%2 == 0 {
leftFork.Lock()
rightFork.Lock()
} else {
rightFork.Lock()
leftFork.Lock()
}
fmt.Printf("Philosopher %d eating\n", i)
time.Sleep(time.Second)
// one group of philosophers ends with right fork
if i%2 == 0 {
rightFork.Unlock()
leftFork.Unlock()
} else {
leftFork.Unlock()
rightFork.Unlock()
}
}
}
// Steward Solution using buffered channel
package main
import (
"fmt"
"sync"
"time"
)
type Steward struct {
forks chan int
sync.Mutex
}
func main() {
count := 5
var wg sync.WaitGroup
wg.Add(count)
steward := Steward{forks: make(chan int, count)}
for i := 0; i < count; i++ {
steward.forks <- i
}
for i := 0; i < count; i++ {
go philosopher(i, &steward)
}
wg.Wait()
}
func philosopher(i int, steward *Steward) {
for {
fmt.Printf("Philosopher %d thinking\n", i)
time.Sleep(time.Second)
// Ask steward and wait when 2 forks available and then eating
steward.Lock()
for len(steward.forks) < 2 {
time.Sleep(time.Second)
}
i := <-steward.forks
j := <-steward.forks
steward.Unlock()
fmt.Printf("Philosopher %d eating\n", i)
time.Sleep(time.Second)
steward.forks <- i
steward.forks <- j
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment