Golang实现任意个哲学家就餐问题
《现代操作系统》中方法
package main
import (
"fmt"
"sync"
"time"
)
func main() {
run := func(philoCnt int) { //开始执行i个哲学家就餐
var (
thinging = 0
hungry = 1
eating = 2
)
mutex := sync.Mutex{}
philoMutex := make([]sync.Mutex, philoCnt)
state := make([]int, philoCnt)
for i := range philoMutex {
philoMutex[i].Lock() //先全部上锁
}
leftPos := func(i int) int {
return (philoCnt + i - 1) % philoCnt
}
rightPos := func(i int) int {
return (philoCnt + i + 1) % philoCnt
}
test := func(i int) {
if state[i] == hungry && state[leftPos(i)] != eating && state[rightPos(i)] != eating {
state[i] = eating
philoMutex[i].Unlock()
}
}
getForks := func(i int) {
mutex.Lock()
state[i] = hungry
test(i)
mutex.Unlock()
philoMutex[i].Lock()
}
putForks := func(i int) {
mutex.Lock()
state[i] = thinging
test(leftPos(i))
test(rightPos(i))
mutex.Unlock()
}
philosopher := func(i int) {
for {
time.Sleep(time.Second) //think
getForks(i)
time.Sleep(time.Second) //eat
putForks(i)
}
}
//部署i个哲学家
for i := 0; i < philoCnt; i++ {
go philosopher(i)
}
//监视进程,用来显示就餐情况
func() {
for {
mutex.Lock()
fmt.Println(state)
mutex.Unlock()
time.Sleep(100 * time.Millisecond)
}
}()
}
run(5)
}
程序输出为每100ms输出各个哲学家的状态,结果如下:
只利用一个互斥锁的方法
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var (
thinking = 0
hungry = 1
eating = 2
)
run := func(philoCnt int) {
mutex := sync.RWMutex{}
state := make([]int, philoCnt)
for i := range state {
state[i] = thinking
}
leftPos := func(i int) int {
if i == 0 {
return philoCnt - 1
}
return i - 1
}
rightPos := func(i int) int {
if i == philoCnt-1 {
return 0
}
return i + 1
}
protectTest := func(i int) bool {
if state[leftPos(i)] == eating || state[rightPos(i)] == eating {
return false
}
state[i] = eating
return true
}
test := func(i int) bool {
mutex.Lock()
defer mutex.Unlock()
if state[leftPos(i)] == eating || state[rightPos(i)] == eating {
return false
}
state[i] = eating
return true
}
getForks := func(i int) {
mutex.Lock()
state[i] = hungry
mutex.Unlock()
for test(i) == false {
}
}
putForks := func(i int) {
mutex.Lock()
defer mutex.Unlock()
state[i] = thinking
protectTest(leftPos(i))
protectTest(rightPos(i))
}
philosopher := func(i int) {
for {
time.Sleep(time.Second)
getForks(i)
time.Sleep(time.Second)
putForks(i)
}
}
for i := 0; i < philoCnt; i++ {
go philosopher(i)
}
func() {
for {
mutex.RLock()
eatingCnt := 0
for _, val := range state {
if val == eating {
eatingCnt++
}
}
fmt.Println(eatingCnt, state)
mutex.RUnlock()
time.Sleep(100 * time.Millisecond)
}
}()
}
run(5)
}
程序输出为每100ms输出各个哲学家的状态,结果如下:
有疑问加站长微信联系(非本文作者)