Go学习笔记—通道补充

Go学习笔记—通道补充


1、超时处理

超时对于一个连接外部资源,或者其他一些需要花费执行时间操作的程序是很重要的。

在Go语言中,通过channelselect,可以简洁而优雅的处理超时操作。

通过匿名函数实现一个外部调用,在2秒后通过通道c1返回它的执行结果。

func main(){
	c1 := make(chan string,1)
    go func(){
        //设置通道返回结果的时间
		time.Sleep(time.Second * 2)
		c1 <- "result 1"
	}()
}

通过通道选择器select,处理超时操作。

func main(){
    select {
	case res := <-c1:
        //不超时直接返回结果
		fmt.Println(res)
	case <- time.After(time.Second * 1):
        //超时返回下面结果
		fmt.Println("timeout 1")
	}
}

//timeout 1

同样的,设置通道在2秒后返回结果,但是将超时时间设置在3秒后,通道内的值即可正常返回。

func main(){
    c2 := make(chan string,1)
	go func(){
		time.Sleep(time.Second * 2)
		c2 <- "result 2"
	}()

	select {
	case res := <-c2:
		fmt.Println(res)
	case <- time.After(time.Second * 3):
		fmt.Println("timeout 2")
	}
}

//result 2
2、非阻塞通道操作

常规的使用通道发送和接收数据是阻塞的。

使用带default子句的select语句可以实现非阻塞的发送和接收,甚至非阻塞的多路select

在例子中实现,如果messages中存在值,通过select将这个值带入到<- messages case中,否则直接到default子句中执行。

func main(){
    messages := make(chan string)
    //singals := make(chan bool)

    select {
    case msg := <-messages:
        fmt.Println("received message",msg)
    default:
        fmt.Println("no message received")
    }
}

通过例子可以看出,default子句可以在通道中未接收任何值时,向用户提供输出。

保证通道在定义之后,未用来传输数据控制台不报错。

func main(){
    messages := make(chan string)
    
    msg := "hi"

    //go func() {
    //    messages <- msg
    //}()

    select {
    case messages <- msg:
        fmt.Println("sent message",msg)
    //case val := <- messages:
    //  	fmt.Println("received message",val)
    default :
      	fmt.Println("no message sent")
    }
}

//no message sent
3、通道的关闭

关闭一个通道之后,就不可以再向这个通道传输数据。

关闭通道可以用来传输工作已经完成的信息给通道的接收方。

func main(){
    jobs := make(chan int,5)
    done := make(chan bool)

    //发送数据
    for j:=1;j<=3;j++{
       jobs <- j
       fmt.Println("sent job",j)
    }
    close(jobs)
    fmt.Println("sent all jobs")
    
    //接收数据
    go func(){
        time.Sleep(time.Second * 1)
        for {
            j,more := <-jobs
            if more{
                fmt.Println("received job",j)
            }else{
                fmt.Println("received all jobs")
                done <- true
                return
            }
        }
    }()
    
    //通道同步的方法等待任务结束
    <-done
}

我们将使用一个jobs通道来传递main()中Go协程任务执行的结束信息到一个工作Go协程中。当我们没有多余的任务给这个工作Go协程时,我们将close这个jobs通道。

使用j, more := <- jobs循环的从jobs 接收数据。在接收的这个特殊的二值形式的值中,如果 jobs 已经关闭了,并且通道中所有的值都已经接收完毕,那么more的值将是false。当我们完成所有的任务时,将使用这个特性通过done通道去进行通知。

4、通道的遍历

从通道关闭中,可以看出在通道关闭后,通道中的值还是可以被遍历出来的。

一个非空的通道时可以关闭的,但是在通道中剩下的值依然可以被接收到。

func main(){
    queue := make(chan string,2)
    queue <- "on"
    queue <- "sky"
    close(queue)

    for elem := range queue{
        fmt.Println(elem)
    }
}

对通道使用for...range...进行遍历,只有需要定义一个变量用来存储值即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值