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

在这种情况下我需要互斥量吗?我正在用一个 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

            }


...


侃侃尔雅
浏览 106回答 2
2回答

慕桂英3389331

规则很简单:如果从多个 goroutine 访问一个变量并且其中至少有一个是写入,则需要显式同步。在您的情况下是这样:您的一个 goroutine 写入token变量(还有err变量!),另一个 goroutine 读取它,因此您必须同步访问。由于token它不是结构的一个字段threatq,因此放置保护它的互斥量并不明智。始终将互斥量放在它应该保护的数据附近。一些注意事项:如前所述,您还err从多个 goroutine 中写入和读取局部变量。你不应该这样做,而是创建另一个局部变量来保存来自其他 goroutines 的错误(除非你想“translfer” goroutines 之间的错误,但这里不是这种情况)。

HUWWW

是的,您也可以尝试在启用标志的情况下运行此测试-race。Go 的竞争检测器可能会告诉您令牌是跨多个 goroutine 的共享变量。因此,必须使用Mutex或 来保护它RWMutex。在您的情况下,我认为这RWMutex更合适,因为有一个 goroutinetoken每 30 分钟更改(即写入)状态,而另一个 goroutine 读取其值。如果您不使用锁保护共享变量,第二个 goroutine 可能会读取旧值token,这可能已过期。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go