如何实现 pop -> 做某事 -> 使用 goroutines 推送队列

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

  • 弹出第一个元素

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

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

我可以为单个 goroutine 做,但是一旦我添加了一段时间,一切都会出错,因为似乎创建了太多的 goroutine。即使放一个else {return}也不能解决问题。附带问题:为什么不呢?我收到错误:

syntax error: unexpected semicolon or newline before else

syntax error: unexpected }


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)

}


人到中年有点甜
浏览 242回答 2
2回答

白衣染霜花

您的代码存在多个问题。else始终与if的右大括号在同一行。请阅读有关此的规范。time.Sleep将time.Duration其作为参数,以纳秒为单位。如果要休眠 2 秒钟,请使用time.Sleep(2*time.Second).for range&nbsp;不需要推送。你的 forfor只是一遍又一遍地产生数百万个 goroutine。Gooutintes 是轻量级的,但不是免费的。添加某种同步机制来控制您正在运行的 goroutine 数量。这是一个稍微好一点的版本。它有效,即使time.Sleep用作同步机制是您永远不应该做的事情。

DIEA

(缓冲的)通道是一个队列,而不是一个堆栈。因此,在这种情况下推和弹出没有意义。堆栈是 LIFO(后进先出),就像旅行行李一样——你先把你需要的东西放在最后。队列是 FIFO(先进先出),就像您将弹珠推过的管道。在队列的上下文中,你被称为入队和出队元素。考虑到所有这些,这就是我解释你想要做的:创建一个缓冲通道(缓冲意味着它可以容纳许多元素,有效地使其成为一个队列)。然后用一堆随机数填充它迭代它并再次仅将那些偶数加入队列,向它们添加 1。尝试实现这个新算法。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go