经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Go语言 » 查看文章
golang select 和外层的 for 搭配
来源:cnblogs  作者:ercom  时间:2024/5/22 9:36:48  对本文有异议

 

select语句通常与for循环搭配使用,但并不是必须的。

在某些情况下,select可能会直接放在一个独立的goroutine中,没有外层的for循环。

这通常发生在你知道只会有一次或有限次操作的情况下。

例如,你可能有一个简单的goroutine,它等待一个特定的channel信号,然后执行一次操作:

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func main() {
  7. interrupt := make(chan struct{})
  8. go func() {
  9. // 假设这是接收中断信号的goroutine
  10. <-interrupt
  11. fmt.Println("Interrupt received, shutting down.")
  12. }()
  13. // 等待中断信号,无需for循环
  14. select {
  15. case <-interrupt:
  16. return
  17. }
  18. }

 

在这个例子中,select会阻塞,直到interrupt channel有数据可读。

一旦接收到数据,select就会结束,程序执行后续的关闭操作。

 

然而,在大多数并发场景中,select与for循环结合使用,以便在多个channel之间持续轮询,直到满足某种退出条件。

在两个或更多goroutine之间使用select时,外层的for循环通常是用来处理以下情况:

1 持久监听:select可能会持续等待来自不同goroutine的消息,这意味着我们需要保持select语句的活性,直到遇到某个特定的退出条件。for循环可以保证这一点,直到出现特定的退出条件(例如,所有的channel都被关闭,或者接收到特定的信号)。

2 非阻塞性检查:即使没有数据可读或可写,for循环也可以配合default子句,用于周期性地检查某些条件,或者执行其他的非阻塞操作。

3 控制并发行为:通过for循环,我们可以控制并发行为,例如限制并发的数量,或者在处理完一批任务后才启动新的任务。

4 处理不确定的结束条件:在并发环境中,何时结束往往不是预先确定的,for循环允许我们持续监控直到满足结束条件,比如所有的工作都被完成。


下面是一个简单的例子,展示了select和for循环的组合,用于处理两个channel的数据:

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func main() {
  7. intChan1 := make(chan int)
  8. intChan2 := make(chan int)
  9. // 启动两个goroutines,分别向两个channel发送数据
  10. go func() {
  11. for i := 1; i <= 5; i++ {
  12. intChan1 <- i
  13. time.Sleep(100 * time.Millisecond)
  14. }
  15. close(intChan1)
  16. }()
  17. go func() {
  18. for i := 6; i <= 10; i++ {
  19. intChan2 <- i
  20. time.Sleep(150 * time.Millisecond)
  21. }
  22. close(intChan2)
  23. }()
  24. // 使用for循环处理两个channel的数据,直到它们都关闭
  25. for {
  26. select {
  27. case value := <-intChan1:
  28. fmt.Printf("Received from channel 1: %d\n", value)
  29. case value := <-intChan2:
  30. fmt.Printf("Received from channel 2: %d\n", value)
  31. // 当所有channel都关闭时,for循环自然结束
  32. case <-time.After(1 * time.Second):
  33. fmt.Println("Both channels closed, exiting.")
  34. return
  35. }
  36. }
  37. }

 

在这个例子中,for循环会一直运行,直到两个channel都被关闭,或者超时退出。

case <-time.After(1 * time.Second): 是Go中一个常见的用法,它用于在select语句中设置一个超时条件。

这里的 time.After 函数返回一个channel,当指定的时间过去后,这个channel会发送一个空的结构体【 <-time.After(1 * time.Second) 会从这个channel中接收这个空结构体 】。

在select中,如果有多个case,它会等待可以执行的case,包括这个超时case。

 

Tool:代码差异比较器HTML查错器Llama3在线SQL格式化

Link:https://www.cnblogs.com/farwish/p/18205120

原文链接:https://www.cnblogs.com/farwish/p/18205120

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号