为了账号安全,请及时绑定邮箱和手机立即绑定

在不同的 goroutine 中替换字符串的值时是否需要互斥量?

在不同的 goroutine 中替换字符串的值时是否需要互斥量?

Go
侃侃尔雅 2023-06-19 15:51:48
在这种情况下我需要互斥量吗?我正在用一个 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 之间的错误,但这里不是这种情况)。

查看完整回答
反对 回复 2023-06-19
?
HUWWW

TA贡献1874条经验 获得超12个赞

是的,您也可以尝试在启用标志的情况下运行此测试-race。Go 的竞争检测器可能会告诉您令牌是跨多个 goroutine 的共享变量。因此,必须使用Mutex或 来保护它RWMutex

在您的情况下,我认为这RWMutex更合适,因为有一个 goroutinetoken每 30 分钟更改(即写入)状态,而另一个 goroutine 读取其值。

如果您不使用锁保护共享变量,第二个 goroutine 可能会读取旧值token,这可能已过期。


查看完整回答
反对 回复 2023-06-19
  • 2 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信