首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【Kotlin 】Channel 通道 ④ ( Channel 通道热数据流属性 | Channel 通道关闭过程 | Channel 通道关闭代码示例 )

文章目录 一、Channel 通道热数据流属性 二、Channel 通道关闭过程 三、Channel 通道关闭代码示例 一、Channel 通道热数据流属性 ---- 调用 CoroutineScope...#produce 函数 构造 生产者 , 以及 调用 CoroutineScope#actor 函数 构造 消费者 , 如果上述 生产者 和 消费者 执行完毕 , 则 对应 Channel...通道 也会进行关闭 , 因此 , Channel 通道 被称为 热数据流 ; 与 Channel 通道 热数据流 相对是 Flow 异步流 冷数据流 特征 ; 二、Channel 通道关闭过程 -...true ; Channel 通道存在缓冲区 , 通道不接收新元素 , 但是 缓冲区已存储元素需要被处理完毕 , 然后才能关闭通道 , 当 Channel 通道 缓冲区 所有的元素处理完毕 , 调用...一次性将 3 个数据全部发送出去 , 但是 数据消费者 每秒只能消费一个数据 , 需要 3 秒才能将数据处理完毕 ; 在发送完数据 , 调用 Channel#close 函数 , 关闭通道 , 此时

46420

【Kotlin 多路复用技术 ① ( 多路复用技术 | await 多路复用 | Channel 通道多路复用 )

文章目录 一、多路复用技术 二、await 多路复用 三、Channel 通道多路复用 一、多路复用技术 ---- 在信号传输时 , 通信信道 带宽 远大于 传输单一信号需求 , 在同一信道中可以同时传递...多路 信号 , 该技术成为 " 多路复用技术 " ; 二、await 多路复用 ---- 在 中 , 可以通过 复用 多个 await 方式 , 实现 多路复用 ; 使用场景 : 使用 不同..., 分别从 网络 和 本地 获取数据 , A 从网络获取数据 , B 从本地获取数据 , 哪个协 先返回 , 则 优先使用该返回数据 ; 在 select 代码块中 , 同时 调用...Job.onAwait 函数 , 同时执行两个协, 哪个先执行完毕, 就取哪个协执行结果 ; // 同时执行两个协, 哪个先执行完毕, 就取哪个协执行结果...---- Channel 通道多路复用 , 就是 多个 Channel 通道同时 传递消息 , 取传递消息最快 Channel 通道信息 ; 代码示例 : package kim.hsl.coroutine

75920
您找到你想要的搜索结果了吗?
是的
没有找到

golang面试官:for select时,如果通道已经关闭会怎么样?如果select中只有一个case呢?

解释 1.for循环里被关闭通道 c通道是一个缓冲为0通道,在main开始时,启动一个对c通道写入10,然后就关闭掉这个通道。...在main中通过 x, ok := <-c 接受通道c里值,从输出结果里看出,确实从通道里读出了之前塞入通道10,但是在通道关闭,这个通道一直能读出内容。...2.怎么样才能不读关闭通道 x, ok := <-c 返回值里第一个x是通道值,ok是指通道是否关闭,当通道关闭,ok则返回false,因此可以根据这个进行操作。...至于为什么读一个未初始化通道会出现阻塞,可以看我另一篇 对未初始化chan进行读写,会怎么样?为什么? 。select中如果任意某个通道有值可读时,它就会被执行,其他被忽略。...此时将通道置为nil 第三次读取case时main会被阻塞,此时整个进程没有其他活动了,进程deadlock 总结 select中如果任意某个通道有值可读时,它就会被执行,其他被忽略

1.3K10

golang面试官:for select时,如果通道已经关闭会怎么样?如果select中只有一个case呢?

解释 1.for循环里被关闭通道 c通道是一个缓冲为0通道,在main开始时,启动一个对c通道写入10,然后就关闭掉这个通道。...在main中通过 x, ok := <-c 接受通道c里值,从输出结果里看出,确实从通道里读出了之前塞入通道10,但是在通道关闭,这个通道一直能读出内容。...2.怎么样才能不读关闭通道 x, ok := <-c 返回值里第一个x是通道值,ok是指通道是否关闭,当通道关闭,ok则返回false,因此可以根据这个进行操作。...至于为什么读一个未初始化通道会出现阻塞,可以看我另一篇 对未初始化chan进行读写,会怎么样?为什么? 。select中如果任意某个通道有值可读时,它就会被执行,其他被忽略。...第一次读取case能读到通道10 第二次读取case能读到通道已经关闭信息。此时将通道置为nil 第三次读取case时main会被阻塞,此时整个进程没有其他活动了,进程deadlock

13900

GO通道和 sync 包分享

是一种特殊类型,是连接并发goroutine管道 channel 通道是可以让一个 goroutine 发送特定值到另一个 goroutine 通信机制。...,也就是说,从 ch 中读出一个数据,赋值给 num 我们从通道中读出数据,也可以不进行赋值,直接忽略也是可以,如: <-ch 关闭通道 Go中提供了 close 函数来关闭通道 close(ch)...对于关闭通道非常需要注意,用不好直接导致程序崩溃 只有在通知接收方 goroutine 所有的数据都发送完毕时候才需要关闭通道 通道是可以被垃圾回收机制回收,它和关闭文件是不一样,在结束操作之后关闭文件是必须要做...,但关闭通道不是必须 关闭通道有以下 4 个特点: 对一个关闭通道再发送值就会导致 panic 对一个关闭通道进行接收会一直获取值直到通道为空 对一个关闭并且没有值通道执行接收操作会得到对应类型零值...阻塞 接收数据 阻塞 接收数据 接收数据 发送数据 阻塞 发送数据 发送数据 阻塞 发送数据 关闭 panic 关闭通道成功待数据读取完毕返回零值 关闭通道成功直接返回零值 关闭通道成功待数据读取完毕返回零值

1K30

Golang并发:并发优雅退出

它在并发中使用场景是:当只从1个channel读取数据,然后进行处理,处理退出。下面这个示例程序,当in通道关闭时,可自动退出。...继续在关闭通道上写,将会panic。 问题2可以这样解决,通道只由发送方关闭,接收方不可关闭,即某个写通道只由使用该select关闭,select中就不存在继续在关闭通道上写数据问题。...问题1可以使用,ok来检测通道关闭,使用情况有2种。 第一种:如果某个通道关闭,需要退出,直接return即可。...技巧:把接收方通道入参声明为只读,如果接收关闭只读,编译时就会报错。 处理1个通道,并且是读时,优先使用for-range,因为range可以关闭通道关闭自动退出。...,ok可以处理多个读通道关闭,需要关闭当前使用for-select。 显式关闭通道stopCh可以处理主动通知退出场景。

5.1K30

GO 语言并发模式你了解多少?

,咱们需要关注两类,一种是一次性任务,咱们 go 出来,执行简单任务完毕直接退出,一种是常驻程序,需要优雅退出,处理一些垃圾回收事情 例如这样: 主程序中设置一个通道变量 ch ,类型为 os.Signal...j 通道时候,得到 ok 为 false,进而所有子退出 wg.Wait() 等待所有子退出,再在 quit 中写入数据 主此时从 quit 中读取到数据,则知道所有子全部退出...,并将取出数据乘以 3 ,将结果写入到 ch2 中 主就阻塞读取 ch2 内容,读取到内容,挨个打印出来 管道模式有两种模式,扇出模式 和 扇入模式,这个比较好理解 扇出模式:多种类型数据从同一个通道...channel 中读取数据,直到通道关闭 扇入模式:输入时候有多个通道channel,程序将所有的通道内数据汇聚,统一输入到另外一个通道channel A 里面,另外一个程序则从这个通道channel...,启动一个 在 3 秒关闭上下文 使用 for 循环模拟处理业务,默认会走 select default 分支 3 秒 走到 select ctx.Done(),则进入到了取消模式,程序退出

25520

15.Go语言-通道

15.4 通道关闭 对于一个已经使用完毕通道,我们要将其进行关闭。...close(channel_name) 这里要注意,对于一个已经关闭通道如果再次关闭会导致报错,我们可以在接收数据时,判断通道是否已经关闭,从通道读取数据返回第二个值表示通道是否没被关闭,如果已经关闭...分析完引发异常原因,我们可以将代码修改如下,使用,将接收者代码放在另一个里: package main import ( "fmt" "time" ) func funcRecieve...Done:当某个子完成,可调用此方法,会从计数器上减一,即子数量减一,通常使用 defer 来调用。 Wait:阻塞当前,直到实例里计数器归零。...15.12.1 使用信道 信道可以实现多个协通信,于是乎我们可以定义一个信道,在任务执行完成,往信道中写入 true ,然后在主中获取到 true ,就可以认为子已经执行完毕。

54130

Go并发编程

(){} // 开启执行这个函数 go func(){} } go入口函数是main函数,相当于主线程,其内部调用其他函数才能开启,而main函数执行完,不管函数是否执行完了...,你传入值会往计数器上加,这里直接传入你子数量,参数值要等于go数量,否则会报错,暂不知道怎么来确定这个值哦 Done:当某个子完成,可调用此方法,会从计数器上减一,通常可以使用 defer...Done:返回一个只读通道(只有在被cancel才会返回),类型为 struct{}。...为什么需要Context goroutine开启,我们是无法强制关闭,一般关闭原因有如下方式: 执行完成,自己结束后退出,正常关闭 主进程异常,导致被迫退出,异常关闭,需要优化代码...通过通道发送信号,引导退出,开发者手动控制 ::: details 手动控制关闭 func main() { stopChan := make(chan bool) manualControlChan

52800

原来服务端退出姿势也可以这么优雅

使用 2 个 channel 来实现优雅关闭 这个方法比较容易想到 实现大体分为 2 步走: 主收到中断信号,通知子优雅关闭 ,这里命名为 stopCh 子收到通知,处理完手头通知主关闭程序...开辟一个,执行匿名函数来监听 stopCh 通道是否有数据,若有数据,说明主收到了信号,并且通知子要优雅关闭了 这个时候,子做完自己事情,就在 closeCh 写入数据,通知主可以正常关闭程序了...,当主关闭上下文时候,子就会从通道到读取到数据,进而进行优雅关闭,我们可以看到源码,ctx.Done() 返回值也是一个通道等待所有子优雅关闭实现方法 上面我们说到都是主等待...1 个子优雅关闭,自己关闭程序 那么实际工作中肯定是不止一个,咱们要做优雅,那就优雅到底 ,此处我们处理方式是 golang 中 context + sync.WaitGroup 方式来实现...cancle() 掉 ctx 每一个子都能从 ctx.Done() 读取到数据,自行处理完毕手中事情 最终 defer mywg.Done() ,主 mywg.Wait() 等待所有都优雅关闭

29620

Coroutine()(三)

() // 我们结束发送 } // 这里我们使用 `for` 循环来打印所有被接收到元素(直到通道关闭) for (y in channel) println(y) println("Done!")...4.带缓冲通道 到目前为止展示通道都是没有缓冲区。无缓冲通道在发送者和接收者相遇时传输元素(也称“对接”)。...} 使用缓冲通道并给 capacity 参数传入 4 它将打印“sending” 五 次,并且在试图发送第五个元素时候被挂起 二、异常处理与监督 1.异常传播 构建器有两种形式:自动传播异常...当这些构建器用于创建一个根时,即该不是另一个, 前者这类构建器将异常视为未捕获异常,类似 Java Thread.uncaughtExceptionHandler, 而后者则依赖用户来最终消费异常...内部使用 CancellationException 来进行取消,这个异常会被所有的处理者忽略,所以那些可以被 catch 代码块捕获异常仅仅应该被用来作为额外调试信息资源。

49020

Go 语言并发编程系列(五)—— 通道类型篇:基本语法和缓冲通道

,用于指定通道最多可以缓存多少个元素,默认值是 0,此时通道可以被称作非缓冲通道,表示往通道中发送一个元素,只有该元素被接收才能存入下一个元素,与之相对,当缓存值大于 0 时,通道可以称作缓冲通道...,直到通道中写入了数据;反过来,如果通道中已经有了数据,再往里面写入数据的话,也会导致写入操作所在阻塞,直到其中数据被其他接收。...,我们可以一直往 ch 通道中写入 10 个数据,超过 10 个数据才会阻塞当前,直到通道被其他读取,显然,合理设置缓冲区可以提高通道操作效率,尤其是在需要持续传输大量数据场景。...,缓冲大小是 20,然后将其传递到子,并且在子中发送数据到通道,子执行完毕,调用 close(ch) 显式关闭通道,这一行不能漏掉,否则主不知道子什么时候执行完毕,从一个空通道接收数据会报如下运行时错误...回到主,我们通过 i := range ch 循环从通道中读取数据,并将其打印出来。当通道关闭后会退出循环。我们对主执行时间做了统计,以对比不使用缓冲通道耗时。

72330

go 并发模式之一,池(pool)

池就是提前创建一些(goroutine),当有任务来时,从这些中选择一个空闲来执行任务,任务执行完后继续保持这个协,以便下次任务到来时复用,避免频繁地创建和销毁,提高程序性能和效率...go worker(w, jobs, results)//job:jobs 通道用于向工作者发送任务,esults 通道用于接收工作者处理任务结果。...close(jobs)//调用 close(jobs) 关闭了 jobs 通道,表示不再向其中提交新任务 // 获取处理结果 var wg sync.WaitGroup wg.Add(numJobs...//通过匿名函数启动了一个新,用于等待所有任务完成关闭 results 通道: go func() { wg.Wait()//等待所有的任务完毕,就执行以下.关闭 results...、 没有任务提交关闭任务jobs通道. 等待所有的任务完成关闭results通道 wg.Done() 减少等待组计数器,表示有一个任务已经完成。 */

8210

Go使用chan或context退出

问题go两个协使用了同一个文件句柄,其中一个关闭了这个文件句柄并退出了,如何及时通知另一个退出?分析当一个关闭了这个文件对象,底层文件文件描述符就会被释放。...这个时候,另一个还持有着同一个文件对象,但其实对应文件描述符已经不存在了。所以当第二个通过这个文件对象再对文件进行操作时候,例如读写文件等,就会发生异常,比如文件描述符不存在错误等。...解决为了避免这个问题,共享文件对象多个协需要通过一个通道或锁进行协调:每个协在使用文件对象前需要获得锁或从通道接收通知。最后关闭文件对象关闭,通过通道或解锁来通知其他对象已经无效。...其他收到通知,就不再对这个已关闭文件对象进行操作。1. 使用 channel 通道在主中,可以定义一个 channel,用来通知其它退出。...使用 context 包Go 语言标准库中提供了 context 包,可以用来控制生命周期。

40010

这些 channel 用法你都用起来了吗?

分别开辟两个子,其中子 1 在 2 秒之后写入数据给到 c1,另外一个子 2 在 1 秒之后写入数据给到 c2 主循环等待阻塞读取 c1 , c2 里面的数据,读取将对应标识 ok1...关闭通道通道变量不应该就变成 nil 了吗?为什么我们还要自己去设置为 nil? 实际上这就是我们对于通道基础知识不扎实了,关闭通道通道本身并不会变为 nil。...通道变量仍然持有通道地址,只是通道状态变为了已关闭 巧用无缓冲 channel 通道 对于无缓冲 channel 通道,只有在对其进行接收操作 goroutine 和对其进行发送操作 goroutine...信号传递 信号传递我们就可以用在两个协一对一传递信号上面,当然我们也可以使用在主主动通知所有子关闭全场景下,这就是一对多传递信号,相关 demo 可以在这期文章中有展示 GO 语言并发模式...一对一(一个发一个收) 一对多(一个发多个收,此处可以是 1 close 掉 通道,那么 多个协默认都能够读取到通道值是零值,此时多个子就可以根据通道关闭状态来处理后续逻辑)

19110

GoLang通道---中

GoLang通道---中 同步:关闭通道-测试阻塞通道 使用 select 切换 通道、超时和计时器(Ticker) 习惯用法:简单超时模式 和恢复(recover) ---- 同步...因为这会自动检测通道是否关闭: for input := range ch { process(input) } 关于通道关闭小结: 只有接收方goroutine所有的数据都发送完毕才会关闭...对一个关闭并且没有值通道执行接收操作,会得到对应类型零值。 关闭一个已经关闭通道会导致panic。 ---- 阻塞和生产者-消费者模式: 在通道迭代器中,两个协经常是一个阻塞另外一个。...如果消费者在独立内核运行,就有可能让不会出现阻塞。 由于容器中元素数量通常是已知,需要让通道有足够容量放置所有的元素。这样,迭代器就不会阻塞(尽管消费者仍然可能阻塞)。...以下代码,在 timeoutNs 纳秒执行 select timeout 分支,执行client.Call 也随之结束,不会给通道 ch 返回值: ch := make(chan error

76510

大道如青天,来通信,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang通道channel使用EP14

然后把这个对象指针传入某个通道变量中,另外一个从这个通道中读出变量指针,并处理其指向内存对象。    ...随后在main函数中,可以理解为主,创建通道ch1,执行开启任务job,在job函数内,往通道内传递数字1     接着,主获取通道内由job传递数据: 0x1400006a060 data...而通道出现,就间接帮我们实现了“阻塞”主目的。    ...,操作number变量,累加通道中写入,程序返回: Final output 30     理论上,如果是并发执行,返回值应该是20或者10,但由于通道存在,造成任务阻塞,变回了同步执行,所以返回了...类似while,它轮询通道是否在发送数据,使用变量ok进行判断。如果ok是假,则意味着通道关闭,因此循环结束,否则将会继续进行无限轮询。

17920
领券