【问题标题】:Golang ticker concurrency issueGolang 代码并发问题
【发布时间】:2020-02-17 17:12:35
【问题描述】:

我有一个用 Golang 写的函数如下

func (participant *SimulationParticipant) StartTransactionsGatewayTicker() {
//Gateway
logging.InfoLogger.Printf("StartTransactionsGatewayTicker:%v", participant.Participant)
ticker := time.NewTicker(1 * time.Second)
participant.TransactionGatewayTicker = ticker
go func() {
    for {
        select {
        case <-ticker.C:
            logging.InfoLogger.Printf("Tick at: %v", participant.Participant)
            participant.GetTransactions()
        }
    }
}()
}

我在循环中调用该函数,就像数组中的 2 SimulationParticipant 一样。 令人惊讶的是,第一个参与者被第二个参与者取代,并且 GetTransactions 总是被执行到循环中的最后一项?我该如何克服这个

【问题讨论】:

  • 请显示调用此方法的代码。如果你在循环变量上调用方法并且它不是指针,participant 的值将始终是指向同一个循环变量的指针,所以当 goroutine 引用它时,它总是会看到变量的值在那一刻有。

标签: go goroutine ticker


【解决方案1】:

为我工作(我发布此代码时没有看到您如何调用 StartTransactionsGatewayTicker,如果不适用,请勿投反对票:P):

// [Timers](timers) are for when you want to do
// something once in the future - _tickers_ are for when
// you want to do something repeatedly at regular
// intervals. Here's an example of a ticker that ticks
// periodically until we stop it.

package main

import (
    "fmt"
    "time"
)

func main() {

        part1 := SimulationParticipant{}
    part1.id = "part1"
        part2 := SimulationParticipant{}
        part2.id = "part2"
        partSlice := make([]*SimulationParticipant,0)
        partSlice = append(partSlice, &part1, &part2)

        for _ , p := range partSlice {
             p.StartTransactionsGatewayTicker()
        }

    // Tickers can be stopped like timers. Once a ticker
    // is stopped it won't receive any more values on its
    // channel. We'll stop ours after 16000ms.
    time.Sleep(16000 * time.Millisecond)
    part1.ticker.Stop()
    part2.ticker.Stop()
    fmt.Println("Ticker stopped")
}

type SimulationParticipant struct {
     id string
     ticker *time.Ticker
}

func (participant *SimulationParticipant) StartTransactionsGatewayTicker() {

ticker := time.NewTicker(1 * time.Second)
participant.ticker = ticker
go func() {
    for {
        select {
        case t := <-ticker.C:
            fmt.Println("Tick at", t,participant.id)
        }
    }
}()
}

输出:

Tick at 2009-11-10 23:00:01 +0000 UTC m=+1.000000001 part2
Tick at 2009-11-10 23:00:01 +0000 UTC m=+1.000000001 part1
Tick at 2009-11-10 23:00:02 +0000 UTC m=+2.000000001 part1
Tick at 2009-11-10 23:00:02 +0000 UTC m=+2.000000001 part2
Tick at 2009-11-10 23:00:03 +0000 UTC m=+3.000000001 part2
Tick at 2009-11-10 23:00:03 +0000 UTC m=+3.000000001 part1
Tick at 2009-11-10 23:00:04 +0000 UTC m=+4.000000001 part1
Tick at 2009-11-10 23:00:04 +0000 UTC m=+4.000000001 part2
Tick at 2009-11-10 23:00:05 +0000 UTC m=+5.000000001 part2
Tick at 2009-11-10 23:00:05 +0000 UTC m=+5.000000001 part1
Tick at 2009-11-10 23:00:06 +0000 UTC m=+6.000000001 part1
Tick at 2009-11-10 23:00:06 +0000 UTC m=+6.000000001 part2
Tick at 2009-11-10 23:00:07 +0000 UTC m=+7.000000001 part2
Tick at 2009-11-10 23:00:07 +0000 UTC m=+7.000000001 part1
Tick at 2009-11-10 23:00:08 +0000 UTC m=+8.000000001 part1
Tick at 2009-11-10 23:00:08 +0000 UTC m=+8.000000001 part2
Tick at 2009-11-10 23:00:09 +0000 UTC m=+9.000000001 part2
Tick at 2009-11-10 23:00:09 +0000 UTC m=+9.000000001 part1
Tick at 2009-11-10 23:00:10 +0000 UTC m=+10.000000001 part1
Tick at 2009-11-10 23:00:10 +0000 UTC m=+10.000000001 part2
Tick at 2009-11-10 23:00:11 +0000 UTC m=+11.000000001 part2
Tick at 2009-11-10 23:00:11 +0000 UTC m=+11.000000001 part1
Tick at 2009-11-10 23:00:12 +0000 UTC m=+12.000000001 part1
Tick at 2009-11-10 23:00:12 +0000 UTC m=+12.000000001 part2
Tick at 2009-11-10 23:00:13 +0000 UTC m=+13.000000001 part2
Tick at 2009-11-10 23:00:13 +0000 UTC m=+13.000000001 part1
Tick at 2009-11-10 23:00:14 +0000 UTC m=+14.000000001 part1
Tick at 2009-11-10 23:00:14 +0000 UTC m=+14.000000001 part2
Tick at 2009-11-10 23:00:15 +0000 UTC m=+15.000000001 part2
Tick at 2009-11-10 23:00:15 +0000 UTC m=+15.000000001 part1
Ticker stopped

游乐场:https://play.golang.org/p/yfHnrRK1iG8

【讨论】:

  • 太棒了,如果它适合你,请接受答案。
猜你喜欢
  • 1970-01-01
  • 2020-06-17
  • 2021-08-30
  • 2021-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多