为什么 sleep 会禁用 go 中的互斥量?
why sleep will disable the mutex in go?
这是一个buyTicket程序,当ticket为0时,会显示“sell out”。我想知道为什么我不能在buyTicket函数中添加sleep,为什么ticket会是负值?
func(t *Ticket) buyTicket() {
if t.getSpareTicket() <= 0 {
log.Print("sell out")
return
}
t.mu.Lock()
t.numTicket--
time.Sleep(time.Microsecond)
log.Printf("there are %d", t.numTicket)
t.mu.Unlock()
}
func (t *Ticket) getSpareTicket() int{
t.mu.Lock()
defer t.mu.Unlock()
return t.numTicket
}
func main() {
buyer := &Ticket{}
buyer.mu = sync.Mutex{}
buyer.numTicket = 100
for buyer.getSpareTicket() > 0 {
//time.Sleep(time.Microsecond)
go func() {
log.Printf("number buy a ticket")
buyer.buyTicket()
}()
}
time.Sleep(time.Second * 2)
//l := buyer.getSpareTicket()
//fmt.Println(l)
}
当我在函数buyTicket中添加time.sleep(time.microsecond)时,票会是负数,我想知道为什么会这样?
这是结果:
2020/11/15 15:36:00 there are 2
2020/11/15 15:36:00 there are 1
2020/11/15 15:36:00 there are 0
2020/11/15 15:36:00 there are -1
2020/11/15 15:36:00 there are -2
2020/11/15 15:36:00 there are -3
2020/11/15 15:36:00 there are -4
2020/11/15 15:36:00 there are -5
程序存在几个问题:
1- for 循环创建 goroutines 而 备用票数不为零。这将创建许多 goroutine,因为它们不会立即执行并减少票数
2- 在 buyTicket 中,您检查,然后购买。一个goroutine检查后,另一个goroutine可以进去做同样的事情,决定继续并买票。
解决办法是修复 buyTicket 在进入时锁定在退出时解锁,并在不调用 getSpareTicket 的情况下检查票数,因为 getSpareTicket 也锁定了相同的互斥锁,这将导致死锁。
这是一个buyTicket程序,当ticket为0时,会显示“sell out”。我想知道为什么我不能在buyTicket函数中添加sleep,为什么ticket会是负值?
func(t *Ticket) buyTicket() {
if t.getSpareTicket() <= 0 {
log.Print("sell out")
return
}
t.mu.Lock()
t.numTicket--
time.Sleep(time.Microsecond)
log.Printf("there are %d", t.numTicket)
t.mu.Unlock()
}
func (t *Ticket) getSpareTicket() int{
t.mu.Lock()
defer t.mu.Unlock()
return t.numTicket
}
func main() {
buyer := &Ticket{}
buyer.mu = sync.Mutex{}
buyer.numTicket = 100
for buyer.getSpareTicket() > 0 {
//time.Sleep(time.Microsecond)
go func() {
log.Printf("number buy a ticket")
buyer.buyTicket()
}()
}
time.Sleep(time.Second * 2)
//l := buyer.getSpareTicket()
//fmt.Println(l)
}
当我在函数buyTicket中添加time.sleep(time.microsecond)时,票会是负数,我想知道为什么会这样?
这是结果:
2020/11/15 15:36:00 there are 2
2020/11/15 15:36:00 there are 1
2020/11/15 15:36:00 there are 0
2020/11/15 15:36:00 there are -1
2020/11/15 15:36:00 there are -2
2020/11/15 15:36:00 there are -3
2020/11/15 15:36:00 there are -4
2020/11/15 15:36:00 there are -5
程序存在几个问题:
1- for 循环创建 goroutines 而 备用票数不为零。这将创建许多 goroutine,因为它们不会立即执行并减少票数
2- 在 buyTicket 中,您检查,然后购买。一个goroutine检查后,另一个goroutine可以进去做同样的事情,决定继续并买票。
解决办法是修复 buyTicket 在进入时锁定在退出时解锁,并在不调用 getSpareTicket 的情况下检查票数,因为 getSpareTicket 也锁定了相同的互斥锁,这将导致死锁。