登录
首页 >  Golang >  Go问答

Golang defer 有时会失败

来源:stackoverflow

时间:2024-04-18 12:54:35 199浏览 收藏

golang学习网今天将给大家带来《Golang defer 有时会失败》,感兴趣的朋友请继续看下去吧!以下内容将会涉及到等等知识点,如果你是正在学习Golang或者已经是大佬级别了,都非常欢迎也希望大家都能给我建议评论哈~希望能帮助到大家!

问题内容

我正在开发一个具有多个例程的应用程序。处理器接收id(字符串)并执行一些操作。 id 可能会重复,并且我不希望多个例程在另一个例程正在处理 id 时处理该 id。

我使用同步互斥映射。

type cache struct{
   sync.mutex
   ids map[string]struct{}
}

func(c *cache) addifnotpresent(string)bool{
   c.lock()
   defer c.unlock()
   if _, ok := c.ids[id]; ok{
       return false
   }
   c.ids[id] = struct{}{}
   return true
}
func(c *cache) delete(string){
   c.lock()
   defer c.unlock()
   delete(c.ids, id)
}

我的处理器有此映射的一个实例。现在我的流程看起来像这样

func process(string){
   ok := cache.addIfNotPresent(id)
   if !ok{
      return
   }
   defer cache.delete(id)

   ctx, cancel := context.WithTimeout(context.Background(), timeout)
   defer cancel()
   err := doOne(ctx)
   if err {
      return err
   }
   ...
   return nil
}

使用 defer 以便无论处理器中发生什么情况,id 都会被删除。

有时(并非总是)该值不会从地图中被逐出。从日志/指标来看,我确信这不是错误情况,但处理功能已完成,并且密钥未从地图中逐出。

我在这里缺少任何互斥或延迟的行为吗?


解决方案


您如何以及何时进行检查?

您粘贴的函数的代码实际上是在完成时删除键,但在执行完成后,可能会有另一个 goroutine 再次处理(从而添加)相同的键。

以上就是《Golang defer 有时会失败》的详细内容,更多关于的资料请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>