之前一直很少用到条件变量,最近看了看,顺便尝试写了写哲学家就餐问题。
问题描述
如图,五个哲学家围着圆桌吃意面,每位哲学家或者拿起左右手边的叉进食,或者放回两边的叉思考。经典的死锁问题。
An_illustration_of_the_dining_philosophers_problem.png
Code
package main
import (
"fmt"
"sync"
"time"
)
type philosopher struct {
id int
eating bool
left *philosopher
right *philosopher
table *sync.Mutex
cond *sync.Cond
}
func (p *philosopher) run() {
for {
p.think()
p.eat()
}
}
func (p *philosopher) think() {
p.table.Lock()
p.eating = false
p.left.cond.Signal()
p.right.cond.Signal()
p.table.Unlock()
fmt.Printf("==philosopher %d Think\n", p.id)
time.Sleep(time.Second) // 根据需要改成sleep随机时间
}
func (p *philosopher) eat() {
p.table.Lock()
for p.left.eating || p.right.eating {
p.cond.Wait()
}
p.eating = true
p.table.Unlock()
fmt.Printf(" philosopher %d Eat\n", p.id)
time.Sleep(time.Second) // 根据需要改成sleep随机时间
}
func main() {
var table sync.Mutex
var pher [5]philosopher
for i := 0; i < 5; i++ {
pher[i].id = i + 1
pher[i].left, pher[i].right = &pher[(i+4)%5], &pher[(i+1)%5]
pher[i].table = &table
pher[i].cond = sync.NewCond(&table)
}
for i := 0; i < 5; i++ {
go pher[i].run()
}
// 无限等待
var wg sync.WaitGroup
wg.Add(1)
wg.Wait()
}
作者原创,转载请注明出处
网友评论