分享
  1. 首页
  2. 文章

golang-channel

爱吃豆包 · · 1046 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

缓冲的 chan, make(chan int, 缓冲大小):

表示满了 缓冲大小后 就开始堵塞,无法在往 管道 塞入数据

不带缓冲区 chan,make(chan int) :

就是放入数据之后,没有取出这个数据就无法在继续放入数据

 cap(ch1) 可以查看缓冲区长度
 len(ch1) 可以查看缓冲区有多少未读的缓存数据

例子一

package main
import (
 "fmt"
 "time"
)
// 理念:不要通过共享内存来通信;通过通信来共享内存
/**
channel 例子一
 channel 既然有了发送方, 就必须要有接收方!!!
 */
func worker(c chan int) {
 for {
 // 从 channel 里面获取数据,赋值给 n
 n := <-c
 fmt.Println("接收到的数据: ",n)
 }
}
func chanDemo() {
 // var c chan int // 此时 c == nil
 // 创建一个 chan
 c := make(chan int)
 // 接收 channel 的数据,只能在另一个 协程(goruotime)里面才能接收到
 go worker(c)
 // 往 channel 发送数据
 c <- 1
 c <- 2
 // 睡眠一下
 // 因为只能打印出 1,还来不及打印 2 的时候,程序已经结束了
 // 所以睡眠一下
 time.Sleep(time.Millisecond)
}
func main() {
 
}

例子二

package main
import (
 "fmt"
 "time"
)
// 理念:不要通过共享内存来通信;通过通信来共享内存
/**
channel 例子二: channel数组
 */
func worker2(id int, c chan int) {
 for {
 // 从 channel 里面获取数据,赋值给 n
 n := <-c
 fmt.Println("接收到的数据: ",n)
 // 发现输出的顺序不一样,这是因为,运行的时候是乱序的,谁先执行是随机的
 }
}
func chanDemo2() {
 // var c chan int // 此时 c == nil
 var channels [10]chan int // channel 数组
 for i :=0;i < 10 ;i++ {
 // 创建一个 chan
 channels[i] = make(chan int)
 // 接收 channel 的数据,只能在另一个 协程(goruotime)里面才能接收到
 go worker2(i, channels[i])
 }
 // 往 channel 发送数据
 for i :=0;i < 10 ;i++ {
 channels[i] <- 'a' + i
 }
 for i :=0;i < 10 ;i++ {
 channels[i] <- 'A' + i
 }
 // 睡眠一下
 // 因为只能打印出 1,还来不及打印 2 的时候,程序已经结束了
 // 所以睡眠一下
 time.Sleep(time.Millisecond)
}
func main() {
 
}

例子三

package main
import (
 "fmt"
 "time"
)
// 理念:不要通过共享内存来通信;通过通信来共享内存
/**
channel 例子三:把 channel 作为返回值
 在使用 channel 的时候我们要告诉调用者,我这channel的方法是发送数据的,还是接收数据的
 chan<- int 表示发送数据
 <-chan int 表示接受数据
 针对下面的例子就是:
 chan<- int 表示发送数据,但是我里面同时也做了接收操作,那么我的里面就是接受数据
 <-chan int 表示接受数据,但是我里面做了发送操作,那么我的里面就是发送数据
 */
 // 表示一个 发送数据的channel,也就是这个 函数只能写,不能读
func createWorker3(id int) chan<- int {
 // 创建一个channel
 c := make(chan int)
 // 需要在里一个 协程里面接收 channel 的值
 // 不然这个死循环,并且还拿不到 channel 里面的值
 go func() {
 for {
 // 从 channel 里面获取数据,赋值给 n
 n := <-c
 fmt.Println("接收到的数据: ",n)
 // 发现输出的顺序不一样,这是因为,运行的时候是乱序的,谁先执行是随机的
 }
 }()
 return c
}
func chanDemo3() {
 // var c chan int // 此时 c == nil
 var channels [10]chan<- int // channel 数组
 for i :=0;i < 10 ;i++ {
 // 创建一个 chan
 channels[i] = createWorker3(i)
 }
 // 往 channel 发送数据
 for i :=0;i < 10 ;i++ {
 channels[i] <- 'a' + i
 }
 for i :=0;i < 10 ;i++ {
 channels[i] <- 'A' + i
 }
 // 睡眠一下
 // 因为只能打印出 1,还来不及打印 2 的时候,程序已经结束了
 // 所以睡眠一下
 time.Sleep(time.Millisecond)
}
func main() {
 
}

例子四

package main
import (
 "fmt"
 "time"
)
// 理念:不要通过共享内存来通信;通过通信来共享内存
/**
channel 例子四:
 因为 channel 一个协程发送数据,另一个协程就要接收数据!
 在这个过程中就要进行协程的切换比较费资源!
 另一个就是我channel发送后,就要等待被接收,比较麻烦!不接受就要出问题!
 */
// 可以使用一个缓冲区的channel
// 会有性能提升
func bufferedChannel() {
 // 创建一个带有缓冲区的 channel,缓冲区大小为 3
 // 表示只能放 3 个数据的缓冲
 c := make(chan int, 3)
 // 接收者
 go worker4(0, c)
 c <- 'a'
 c <- 'b'
 c <- 'c'
 c <- 'd'
 time.Sleep(time.Millisecond)
}
// 关闭channel 例子
func channelClose (){
 // 创建一个带有缓冲区的 channel,缓冲区大小为 3
 // 表示只能放 3 个数据的缓冲
 c := make(chan int, 3)
 // 接收者
 go worker4(0, c)
 c <- 'a'
 c <- 'b'
 c <- 'c'
 c <- 'd'
 // 我发送方,告诉接收方,我发送数据完毕了,可以关闭了
 // 调用 close(c) 表示关闭,关闭的标记值是 0
 close(c)
 time.Sleep(time.Millisecond)
}
func worker4(id int, c chan int) {
 for {
 // 这种方式接收,n 表示接收到的值,ok 表式是否还有数据可以接收
 n, ok := <-c
 if !ok {
 // 表示结束这个 接收的 协程
 break
 }
 fmt.Printf("接收到的值: %d\n", n)
 }
 // 这个方式也可以,等到我接收完毕,我就跳出去
 // 但这个方式,只要是 发送方没有 close(c) ,就不算结束,只是我这个 for 循环自己跳出了而已
 // 然后等到我这个 main 主函数结束后,我发送方的 协程才算结束
 //for n := range c{
 // fmt.Printf("接收到的值: %d\n", n)
 //}
}
func main() {
 
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:爱吃豆包

查看原文:golang-channel

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
1046 次点击
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏