这是一个buyTicket程序,当ticket为0时,会显示“sell out”。我想知道为什么我不能在 buyTicket 函数中添加 sleep 以及为什么票会是负数? 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) 时,ticket 将为负数,我想知道为什么会这样?这是结果:2020/11/15 15:36:00 there are 22020/11/15 15:36:00 there are 12020/11/15 15:36:00 there are 02020/11/15 15:36:00 there are -12020/11/15 15:36:00 there are -22020/11/15 15:36:00 there are -32020/11/15 15:36:00 there are -42020/11/15 15:36:00 there are -5
1 回答
大话西游666
TA贡献1817条经验 获得超14个赞
程序有几个问题:
1- for 循环创建 goroutines而备用票证的数量非零。这将创建许多 goroutine,因为它们不会立即执行并减少票数
2- 在 buyTicket 中,您检查,然后购买。在一个 goroutine 检查、决定继续并买票后,另一个 goroutine 可以进去做同样的事情。
解决方案是修复buyTicket在退出时锁定进入解锁,并在不调用getSpareTicket的情况下检查票数,因为getSpareTicket也锁定了相同的互斥体,这将导致死锁。
- 1 回答
- 0 关注
- 80 浏览
添加回答
举报
0/150
提交
取消