在这种情况下我需要互斥量吗?我正在用一个 goroutine 刷新令牌,该令牌在另一个 goroutine 中使用。换句话说,我的令牌是否会在某个时候为空,以便响应为401?如果是,它是结构的一部分c *threatq还是一个简单的变量,我的意思是,我的代码中的一个“独立”变量。// IndicatorChannelIterator returns indicators from ThreatQ into a channel.func (c *threatq) IndicatorChannelIterator() (<-chan *models.Indicator, error) { // Authenticate token, err := c.authenticate(c.clientID, c.email, c.password) if err != nil { return nil, fmt.Errorf("Error while authenticating to TQ : %s", err) } // Periodically refresh the token ticker := time.NewTicker(30 * time.Minute) go func() { for range ticker.C { token, err = c.authenticate(c.clientID, c.email, c.password) if err != nil { logrus.Errorf("Error while authenticating to TQ : %s", err) } } }() // Prepare the query query := &Query{} // Get the first page firstTQResponse, err := c.advancedSearch(query, token, 0) if err != nil { return nil, fmt.Errorf("Error while getting the first page from TQ : %s", err) } // Create the channel indicators := make(chan *models.Indicator) // Request the others go func() { req := 1 total := firstTQResponse.Total for offset := 0; offset < total; offset += c.perPage { // Search the indicators tqResponse, err := c.advancedSearch(query, token, offset) if err != nil { logrus.Errorf("Error while getting the indicators from TQ : %s", err) continue }...
2 回答
慕桂英3389331
TA贡献2036条经验 获得超8个赞
规则很简单:如果从多个 goroutine 访问一个变量并且其中至少有一个是写入,则需要显式同步。
在您的情况下是这样:您的一个 goroutine 写入token
变量(还有err
变量!),另一个 goroutine 读取它,因此您必须同步访问。
由于token
它不是结构的一个字段threatq
,因此放置保护它的互斥量并不明智。始终将互斥量放在它应该保护的数据附近。
一些注意事项:如前所述,您还err
从多个 goroutine 中写入和读取局部变量。你不应该这样做,而是创建另一个局部变量来保存来自其他 goroutines 的错误(除非你想“translfer” goroutines 之间的错误,但这里不是这种情况)。
HUWWW
TA贡献1874条经验 获得超12个赞
是的,您也可以尝试在启用标志的情况下运行此测试-race
。Go 的竞争检测器可能会告诉您令牌是跨多个 goroutine 的共享变量。因此,必须使用Mutex
或 来保护它RWMutex
。
在您的情况下,我认为这RWMutex
更合适,因为有一个 goroutinetoken
每 30 分钟更改(即写入)状态,而另一个 goroutine 读取其值。
如果您不使用锁保护共享变量,第二个 goroutine 可能会读取旧值token
,这可能已过期。
- 2 回答
- 0 关注
- 105 浏览
添加回答
举报
0/150
提交
取消