【问题标题】:Golang/Gopher way to manipulate data in different channels?Golang/Gopher 在不同渠道中操作数据的方式?
【发布时间】:2015-08-12 22:23:05
【问题描述】:

新来的,并确保我在正确的页面上使用通道 + 并发我有一个结构

type Playlist struct {
  playList   []*Song
  updateList chan *Song
}

我有 2 个函数在单独的 go 例程中操作数据。

第一个是每当在频道上发送指向歌曲的指针时将数据附加到播放列表:

  func (p *Playlist) continuousUpdate() {
    go func (){
      for newSong := range p.updateList {
        p.playlist = append(p.playlist, newSong)
      }
    }()
  }

第二个,每 24 小时会有一个计时器计时,从而将播放列表重置为一个空片段。

func (p *Playlist) controlCurrentPlayList(c <-chan time.Time) {
  go func(){
    for {
      <-c
      p.playlist = make([]*Song, 0)
      log.Println("Current playlist has reset")
    }
  }()
}

是否有两个独立的通道处理数据同步?还是我很容易陷入比赛状态?

运行go build -race,没有出现错误。

【问题讨论】:

    标签: go


    【解决方案1】:

    因为playlist 字段是从两个没有同步的 goroutine 访问的,所以存在竞争。

    竞争检测器在运行时检测竞争,而不是构建时间。在 24 小时重置计时器计时结束之前,不会检测到这场比赛。

    可以通过使用 select 语句组合两个 goroutine 来消除竞争:

    for {
        select {
        case newSong := <-p.updateList:
            p.playlist = append(p.playlist, newSong)
        case <-c:
            p.playlist = make([]*Song, 0)
            log.Println("Current playlist has reset")
        }
     }
    

    【讨论】:

      猜你喜欢
      • 2020-06-18
      • 2020-09-28
      • 2021-12-20
      • 2017-11-09
      • 2021-08-29
      • 2021-11-28
      • 2017-04-24
      • 2018-06-19
      • 2018-11-17
      相关资源
      最近更新 更多