首页 > 其他分享 >golang select 和外层的 for 搭配

golang select 和外层的 for 搭配

时间:2024-05-21 22:51:32浏览次数:26  
标签:case 外层 goroutine golang 循环 select func channel

 

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

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

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

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

package main

import (
    "fmt"
    "time"
)

func main() {
    interrupt := make(chan struct{})

    go func() {
        // 假设这是接收中断信号的goroutine
        <-interrupt
        fmt.Println("Interrupt received, shutting down.")
    }()

    // 等待中断信号,无需for循环
    select {
    case <-interrupt:
        return
    }
}

 

在这个例子中,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的数据:

package main

import (
    "fmt"
    "time"
)

func main() {
    intChan1 := make(chan int)
    intChan2 := make(chan int)

    // 启动两个goroutines,分别向两个channel发送数据
    go func() {
        for i := 1; i <= 5; i++ {
            intChan1 <- i
            time.Sleep(100 * time.Millisecond)
        }
        close(intChan1)
    }()

    go func() {
        for i := 6; i <= 10; i++ {
            intChan2 <- i
            time.Sleep(150 * time.Millisecond)
        }
        close(intChan2)
    }()

    // 使用for循环处理两个channel的数据,直到它们都关闭
    for {
        select {
        case value := <-intChan1:
            fmt.Printf("Received from channel 1: %d\n", value)

        case value := <-intChan2:
            fmt.Printf("Received from channel 2: %d\n", value)

        // 当所有channel都关闭时,for循环自然结束
        case <-time.After(1 * time.Second):
            fmt.Println("Both channels closed, exiting.")
            return
        }
    }
}

 

在这个例子中,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

标签:case,外层,goroutine,golang,循环,select,func,channel
From: https://www.cnblogs.com/farwish/p/18205120

相关文章

  • mysql: Syntax error or access violation: 1055 Expression #2 of SELECT (错误解决办
    Mysql报错:SQLSTATE[42000]:Syntaxerrororaccessviolation:1055Expression#2ofSELECTlistisnotinGROUPBYclauseandcontainsnonaggregatedcolumn'seo.ryc_combo_class_cate_list_113.fid'whichisnotfunctionallydependentoncolumnsin......
  • Sitecore 设置 SelectItems 最大长度问题
    添加一个configpatch文件即可,然后放在App_Config下,内容如下:sitecore默认value是100。<?xmlversion="1.0"encoding="utf-8"?><configurationxmlns:patch="http://www.sitecore.net/xmlconfig/"xmlns:role="http://www.sitecore.n......
  • MySQL报错:SELECT list is not in GROUP BY clause and contains nonaggregated colum
    报错截图解决方法:修改数据库配置1.查看.sql_mode配置select@@global.sql_mode;2.查看返回信息是否包含ONLY_FULL_GROUP_BYONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION;3.去掉ONLY_FULL_GROUP_BY,其他参数不变,执行即可SETGLOBALsql_mode=‘STRI......
  • JavaScript------querySelector/querySelectorAll的使用
    1、基础语法querySelector()方法返回文档中匹配指定CSS选择器的一个元素。querySelector()方法仅仅返回匹配指定选择器的第一个元素。如果你需要返回所有的元素,请使用querySelectorAll()方法替代。属性:指定一个或多个匹配元素的CSS选择器。可以使用它们的id,类,类......
  • vscode 无法调试 golang testify suite 中的单个 test 的解决办法
    目录问题描述网上的讨论最终的解决办法问题描述对于如下这样简单的测试文件:packagemain//Basicimportsimport( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite")varassertObj*assert.Assertions//Definethesuite,......
  • IO多路复用:Select, Poll与Epoll
    IO多路复用:Select,Poll与Epoll参考:EPOLL原理详解(图文并茂)一、网络数据是如何被接收的网卡接收到网络数据将网络数据暂存到内存当中(DMA传输技术)网卡向CPU发起硬件中断CPU执行中断处理函数,将内存中的数据存储到socket文件描述符中,并唤醒相关进程Q1:如何知道要将网络数据......
  • 连接池设计与实现一——以Golang Http1.1为例
    0.前言连接池是一个非常重要的开发思想,如httpclient会构建连接池复用底层TCP连接,使用database/sql的使用也会有连接池的配置。那么代码底层是如何实现连接池的呢?这篇文档将以Golang语言为基础,分析http1.1连接池底层实现★注意:我们仅仅关注连接池设计思想、以及关键源码解读,......
  • Linux/Golang/glibC系统调用
    Linux/Golang/glibC系统调用本文主要通过分析Linux环境下Golang的系统调用,以此阐明整个流程有时候涉略过多,反而遭到质疑~,写点文章证明自己实力也好Golang系统调用找个函数来分析https://pkg.go.dev/os/exec#Cmd.Wait源码文件在src/os目录下的:exec.go->exec_unix.go->......
  • elementUI 使用 el-select 的远程搜索功能,导致数据无法回显怎么解决?
    问题:解决方法:在数据初始化的时候将获取到的数据做进一步的处理,进行本地select组件的一个添加constlabels=[];constvalues=[];res.data.rows.forEach((ele)=>{labels.push(ele.buildName);values.push(ele.buildCode)......
  • css 让文字不被选中之-moz-user-select 属性介绍
    让文字不被选中,应该有一个css属性进行控制,结果网上查了下发现了-moz-user-select属性介绍 他在ie下也能选中文字,但是选中其他列表,不会选中文字,原来它是在不同div中,属于不同的范围,而同事是放在同一个table中,当然会选中。而在firefox下,文字不会被选中,查看googlecalender的css,原......