您的位置 首页 golang

golang之channel用法

转自 Go Channel 高级实践

用法

  • 超时控制
  • 取最快的结果
  • 限制最大并发数
  • for…range 优先
  • 多个 goroutine 同步响应
  • 非阻塞的 select
  • for{select{}} 终止

1.超时控制

// 利用 time.After 实现func main() {    done := do()    select {    case <-done:        // logic    case <-time.After(3 * time.Second):        // timeout    }}func do() <-chan struct{} {    done := make(chan struct{}, 1)    go func() {        // do something        // ...        done <- struct{}{}    }()    return done}

2.取最快的结果

比较常见的一个场景是重试,第一个请求在指定超时时间内没有返回结果,这时重试第二次,取两次中最快返回的结果使用。
超时控制在上面有,下面代码部分就简单实现调用多次了。

func main() {    ret := make(chan string, 3)    for i := 0; i < cap(ret); i++ {        go call(ret)    }        fmt.Println(<-ret)}func call(ret chan<- string) {    // do something    // ...    ret <- "result"}

3.限制最大并发数

// 最大并发数为 2limits := make(chan struct{}, 2)for i := 0; i < 10; i++ {    go func() {        // 缓冲区满了就会阻塞在这        limits <- struct{}{}        do()        <-limits    }()}

4.for…range 优先

for … range c { do } 这种写法相当于 if _, ok := <-c; ok { do }

func main() {    c := make(chan int, 20)    go func() {        for i := 0; i < 10; i++ {            c <- i        }        close(c)    }()    // 当 c 被关闭后,取完里面的元素就会跳出循环    for x := range c {        fmt.Println(x)    }}

5.多个 goroutine 同步响应

func main() {    c := make(chan struct{})    for i := 0; i < 5; i++ {        go do(c)    }    close(c)}func do(c <-chan struct{}) {    // 会阻塞直到收到 close    <-c    fmt.Println("hello")}

6.非阻塞的 select

select 本身是阻塞的,当所有分支都不满足就会一直阻塞,如果想不阻塞,那么一个什么都不干的 default 分支是最好的选择

select {case <-done:    returndefault:   }

7.for{select{}} 终止

尽量不要用 break label 形式,而是把终止循环的条件放到 for 条件里来实现

for ok {    select {    case ch <- 0:    case <-done:        ok = false    }}

文章来源:智云一二三科技

文章标题:golang之channel用法

文章地址:https://www.zhihuclub.com/7460.shtml

关于作者: 智云科技

热门文章

网站地图