在golang定期冲洗通道

dam*_*mir 10 go

我需要定期刷新频道的内容.我用len()做了这个,我想知道是否有更好的方法来做到这一点.

http://play.golang.org/p/YzaI_2c_-F

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    commch := make(chan int, 100)
    go fillchan(commch)
    drainchan(commch)
}

func fillchan(commch chan int) {
    for {
        select {
        case <-time.Tick(30 * time.Millisecond):
            commch <- rand.Int()
        }
    }
}

func drainchan(commch chan int) {
    for {
        chanlen := len(commch) // get number of entries in channel
        time.Sleep(1 * time.Second)
        for i := 0; i <= chanlen; i++ { //flush them based on chanlen
            fmt.Printf("chan len: %s num: %s\n", chanlen, <-commch)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑1:似乎这是更好的方法来做到这一点 http://play.golang.org/p/4Kp8VwO4yl

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    commch := make(chan int, 1000)
    go fillchan(commch)
    for {
        select {
        case <-time.Tick(1000 * time.Millisecond):
            drainchan(commch)
        }
    }
}

func fillchan(commch chan int) {
    for {
        select {
        case <-time.Tick(300 * time.Millisecond):
            commch <- rand.Int()
        }
    }
}

func drainchan(commch chan int) {
    for {
        select {
        case e := <-commch:
            fmt.Printf("%s\n",e)
        default:
            return
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑2:删除选择,防止内存泄漏随着时间的推移.Tick http://play.golang.org/p/WybAhRE3u4

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    commch := make(chan int, 1000)
    go fillchan(commch)
    for _ = range time.Tick(1000 * time.Millisecond) {
        drainchan(commch)
    }
}

func fillchan(commch chan int) {
    for _ = range time.Tick(300 * time.Millisecond) {
        commch <- rand.Int()
    }
}

func drainchan(commch chan int) {
    for {
        select {
        case e := <-commch:
            fmt.Printf("%s\n", e)
        default:
            return
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Ric*_*777 6

冲洗通道内容的需要是不寻常的.频道不提供此功能 - 但您可以创建一个行为相似的goroutine(...如果您真的想这样做).

通常情况下,您会考虑更多关于在一个通道上输入并在另一个通道上输出的goroutine; 两个通道都具有相同的数据类型.原则上你可以用这种方式模拟所有缓冲的通道; 对于它的客户端,goroutine的行为类似于普通的缓冲通道,因为它传递了它所接收的内容.

将第三个通道添加到goroutine中,并在它和输入之间进行选择.这将允许您在没有竞争条件蔓延的情况下触发清空缓冲区.简单.

现在有三个通道连接到goroutine - 两个输入和一个输出.因此,当您设计将使用它的东西时,您可以推断出数据刷新的语义是什么.

一个亲戚想起来.考虑具有一个输入和一个输出通道的goroutine.它提供了一个固定大小的覆盖缓冲区,即即使输出通道被阻塞也可以随时从其输入通道读取的覆盖缓冲区.这也需要具有默认情况的选择,但不需要第三个通道.覆盖缓冲区有一个明确的用例:当通道和goroutine连接到循环时,很可能发生死锁.覆盖缓冲区作为死锁的一个候选解决方案派上用场,因为一些数据在迟到时是无用的 - 例如,当应用程序太忙而无法响应时,您可以在GUI中丢弃鼠标事件.