go channel 用例

简介: go channel 用例

oroutine

http://127.0.0.1:3999/concurrency/1

doc

https://golang.org/pkg/sync/


go demo


Goroutines run in the same address space, so access to shared memory must be synchronized. The sync package provides useful primitives, although you won’t need them much in Go as there are other primitives. (See the next slide.)

package main
import (
  "fmt"
  "time"
)
func say(s string) {
  for i := 0; i < 5; i++ {
    time.Sleep(100 * time.Millisecond)
    fmt.Println(s)
  }
}
func main() {
  go say("world")
  say("hello")
}

channel

Channels are a typed conduit through which you can send and receive values with the channel operator, <-.

this channel will be block until double side ready.

普通管道 没有缓冲区, 会被 job 两端 阻塞.

直到 双方数据准备好.


使用中 需要 避免死锁.

fatal error: all goroutines are asleep - deadlock!

package main
import "fmt"
func sum(s []int, c chan int) {
  sum := 0
  for _, v := range s {
    sum += v
  }
  c <- sum // send sum to c
}
func main() {
  s := []int{7, 2, 8, -9, 4, 0}
  c := make(chan int)
  go sum(s[:len(s)/2], c)
  go sum(s[len(s)/2:], c)
  x, y := <-c, <-c // receive from c
  fmt.Println(x, y, x+y)
}

Buffered Channels

缓冲管道.

Sends to a buffered channel block only when the buffer is full. Receives block when the buffer is empty.

package main
import "fmt"
func main() {
  ch := make(chan int, 2)
  ch <- 1
  ch <- 2
  fmt.Println(<-ch)
  fmt.Println(<-ch)
}

range and close channel

range 会尝试 持续的 获取 管道 输出, 无输出 时 也会 阻塞, 直到 管道 关闭 才会结束

package main
import (
  "fmt"
)
func fibonacci(n int, c chan int) {
  x, y := 0, 1
  for i := 0; i < n; i++ {
    c <- x
    x, y = y, x+y
  }
  close(c)
}
func main() {
  c := make(chan int, 10)
  go fibonacci(cap(c), c)
  for i := range c {
    fmt.Println(i)
  }
}

judge channel state


Another note: Channels aren’t like files; you don’t usually need to close them. Closing is only necessary when the receiver must be told there are no more values coming, such as to terminate a range loop.

管道 并不像 文件一样. 没有必要 关闭.

除非 接收端 使用了 range , 或者 处于 某种 设计 .


Note: Only the sender should close a channel, never the receiver. Sending on a closed channel will cause a panic.

注意 只有 发送端 应该 关闭 管道, 因为 接受者 关闭 管道 后, 会导致 发送端 引发 异常, ok 探测 也能在 接收端 进行.

v, ok := <-ch
if !ok {
  panic("channel have be closed")
}

select on channel


The select statement lets a goroutine wait on multiple communication operations.

select 让go 协程, 在 多个 通信 操作 之间 等待.


A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.

select 会阻塞, 直到 其中一个 通信 操作 可以 进行.

如果 有 多个 通信 操作 可以执行, 他会 随机选择 一个 去执行.

package main
import "fmt"
func fibonacci(c, quit chan int) {
  x, y := 0, 1
  for {
    select {
    case c <- x:
      x, y = y, x+y
    case <-quit:
      fmt.Println("quit")
      return
    }
  }
}
func main() {
  c := make(chan int)
  quit := make(chan int)
  go func() {
    for i := 0; i < 10; i++ {
      fmt.Println(<-c)
    }
    quit <- 0
  }()
  fibonacci(c, quit)
}

default in select channel


The default case in a select is run if no other case is ready.

当 左右 case 都无法 触发 的 时候, default 会被 执行.


Use a default case to try a send or receive without blocking:

当你 不想 被 通信 锁死的 时候, 请选择 default

package main
import (
  "fmt"
  "time"
)
func main() {
  tick := time.Tick(100 * time.Millisecond)
  boom := time.After(500 * time.Millisecond)
  for {
    select {
    case <-tick:
      fmt.Println("tick.")
    case <-boom:
      fmt.Println("BOOM!")
      return
    default:
      fmt.Println("    .")
      time.Sleep(50 * time.Millisecond)
    }
  }
}
相关文章
|
1月前
|
存储 安全 Java
Go 基础数据结构的底层原理(slice,channel,map)
Go 基础数据结构的底层原理(slice,channel,map)
63 0
|
3天前
|
存储 Go
Go 语言当中 CHANNEL 缓冲
Go 语言当中 CHANNEL 缓冲
|
1月前
|
负载均衡 Go 调度
使用Go语言构建高性能的Web服务器:协程与Channel的深度解析
在追求高性能Web服务的今天,Go语言以其强大的并发性能和简洁的语法赢得了开发者的青睐。本文将深入探讨Go语言在构建高性能Web服务器方面的应用,特别是协程(goroutine)和通道(channel)这两个核心概念。我们将通过示例代码,展示如何利用协程处理并发请求,并通过通道实现协程间的通信和同步,从而构建出高效、稳定的Web服务器。
|
1月前
|
设计模式 缓存 安全
一篇文章带你吃透Go语言的Atomic和Channel--实战方法
一篇文章带你吃透Go语言的Atomic和Channel--实战方法
42 0
|
1月前
|
存储 Go
|
1月前
|
安全 Go 调度
Go语言的并发编程:goroutine和channel详解
Go语言的并发编程:goroutine和channel详解
121 2
|
1月前
|
Go
Go语言Channel进阶:巧妙运用超时机制
Go语言Channel进阶:巧妙运用超时机制
146 0
|
1月前
|
存储 缓存 安全
Go Channel详解
Go Channel详解
89 0
|
1月前
|
Go
一图胜千言,帮你搞懂Go面试中常问的channel问题!
一图胜千言,帮你搞懂Go面试中常问的channel问题!
|
存储 缓存 安全
面试某大厂,被Go的Channel给吊打了,这次一次性通关channel。
面试某大厂,被Go的Channel给吊打了,这次一次性通关channel。
763 0