如何实现pop - >做点什么 - >使用goroutines推送队列

时间:2014-09-24 12:02:24

标签: concurrency go queue goroutine

我有一个队列,我想执行以下操作:

  • 弹出第一个元素

  • 如果元素是偶数,则按元素+1

这应该继续,直到队列为空;此外,我想同时使用多个goroutine。

我可以为单个goroutine做,但是只要我添加一段时间就会出错,因为看起来创建了太多的goroutine。即使放else {return}也无法解决问题。附带问题:为什么不呢?我得到了错误:

syntax error: unexpected semicolon or newline before else
syntax error: unexpected }

Link to Playground

var list = []int{0, 1, 2, 3}

var mutex = &sync.Mutex{}

func pop(out chan int) {
    mutex.Lock()
    element := list[0]
    fmt.Println("element is ", element)
    list = list[1:]
    mutex.Unlock()
    out <- element
}

func push(in chan int) {
    for element := range in {
        if element%2 == 0 {
            mutex.Lock()
            list = append(list, element+1)
            fmt.Println("New list is ", list)
            mutex.Unlock()
        }
    }
}

func main() {
    out := make(chan int)
    fmt.Println("MAIN")

//  for len(list) != 0 {
    go pop(out)
    go push(out)
//}
    time.Sleep(2)
}

2 个答案:

答案 0 :(得分:3)

(缓冲)通道是队列,而不是堆栈。因此,推动和弹出在这种情况下没有意义。

堆叠是LIFO(后进先出),就像旅行行李箱一样 - 你先把你需要的东西放进去。队列是FIFO(先进先出),就像你推动弹珠一样的管子。

在队列的上下文中,你说要将元素排队并出列。

考虑到这一切,这就是我解释你想做的事情:

  • 创建一个缓冲通道(缓冲意味着它可以容纳许多元素,有效地使它成为队列)。
  • 然后填写一堆随机数
  • 对它进行迭代,然后只将那些是偶数的,然后加1。

尝试实施这种新算法。

答案 1 :(得分:2)

您的代码存在多个问题。

  • else始终与if的右括号位于同一行。请阅读the Spec

  • time.Sleeptime.Duration为参数,以纳秒为单位。如果您想睡2秒钟,请使用time.Sleep(2*time.Second)

  • for range不需要推送。

  • 你的for只会反复产生数百万个goroutines。 Goroutintes很轻,但不是免费的。添加某种同步机制来控制正在运行的goroutine的数量。

Here版本略胜一筹。虽然使用time.Sleep作为同步机制是你永远不应该做的事情,但它仍然有用。