首页 > 其他分享 >每日一抄 Go语言使用select切换协程

每日一抄 Go语言使用select切换协程

时间:2022-12-12 12:55:05浏览次数:54  
标签:case 语句 协程 一抄 阻塞 break 表达式 Go select

看了两篇博客,一个说:在任何一个 case 中执行 break 或者 return,select 就结束了。
另一个说:break只能跳出select中的一个case
验证了一下,不知道对不对,感觉是跳出了整个select

func main() {
	v := make(chan int)
	o := make(chan bool)

	select {
	case d := <-v:
		fmt.Println("ddd", d)
	case <-time.After(time.Second * 5):
		fmt.Println("timeout")
		//o <- true
		break
	}
	fmt.Println("ssssssssssssss")

	time.Sleep(time.Second * 100)
	<-o

	fmt.Println("程序结束")
}
package main

import (
	"fmt"
	"time"
)

/*
1.监听的case中,没有满足条件的就阻塞
2.多个满足的条件就任选一个执行
3.select本身不带循环,需要外层的for循环
4.default通常不用,会产生忙轮训
5.break只能跳出select中的一个case

1.加入了默认分支,那么无论涉及通道操作的表达式是否有阻塞,select语句都不会被阻塞。如果那几个表达式都阻塞了,或者说都没有满足求值的条件,那么默认分支就会被选中并执行。

2.如果没有加入默认分支,那么一旦所有的case表达式都没有满足求值条件,那么select语句就会被阻塞。直到至少有一个case表达式满足条件为止。
如果select语句发现同时有多个候选分支满足选择条件,那么它就会用一种伪随机的算法在这些分支中选择一个并执行。注意,即使select语句是在被唤醒时发现的这种情况,也会这样做
*/

/*
go里面提供了一个关键字select,通过select可以监听channel上的数据流动

select的用法与switch语言非常类似,由select开始一个新的选择块,每个选择块条件由case语句来描述

与switch语句可以选择任何可使用相等比较的条件相比,select有比较多的限制,其中最大的一条限制就是每个case语句里必须是一个IO操作
for{
	select {
	case <- chan1:
		//
	case <- chan2:
		//
	default:
		//case表达式都没有满足求值条件,
	}
}
*/

/*
在一个select语句中,go语言会按顺序从头到尾评估每一个发送和接收的语句

如果其中的任意一语句可以继续执行(即没有被阻塞),那么就从哪些可以执行的语句中任意选择一条来使用

如果没有任意一条语句可以执行(即所有的通道都被阻塞),那么有两种可能的情况:

如果给出了default语句,那么就会执行default语句,同时程序的执行会从select语句后的语句中恢复
如果没有default语句,那么select语句将被阻塞,直到至少有一个通信可以进行下去
*/

/*
防止channel超时机制
有时候会出现协程阻塞的情况,那么我们如何避免这个情况?我们可以使用select来设置超时
*/

//func main() {
//	v := make(chan int)
//	o := make(chan bool)
//
//	select {
//	case d := <-v:
//		fmt.Println("ddd", d)
//	case <-time.After(time.Second * 5):
//		fmt.Println("timeout")
//		//o <- true
//		break
//	}
//	fmt.Println("ssssssssssssss")
//
//	time.Sleep(time.Second * 100)
//	<-o
//
//	fmt.Println("程序结束")
//}

//超时这种写法也常常用来设置定时执行某段函数
//go func() {
//	select {
//	case <- time.After(5 * time.Second):
//		dosomething()
//	}
//}

/*
default 语句是可选的;fallthrough 行为,和普通的 switch 相似,是不允许的。在任何一个 case 中执行 break 或者 return,select 就结束了。

select 做的就是:选择处理列出的多个通信情况中的一个。

如果都阻塞了,会等待直到其中一个可以处理
如果多个可以处理,随机选择一个
如果没有通道操作可以处理并且写了default 语句,它就会执行:default 永远是可运行的(这就是准备好了,可以执行)。
在 select 中使用发送操作并且有 default 可以确保发送不被阻塞!如果没有 default,select 就会一直阻塞。

select 语句实现了一种监听模式,通常用在(无限)循环中;在某种情况下,通过 break 语句使循环退出。

*/

func main() {
	ch1 := make(chan int)
	ch2 := make(chan int)

	go pump1(ch1)
	go pump2(ch2)
	go suck(ch1, ch2)
	time.Sleep(1e9)

}

func pump1(ch chan int) {
	for i := 0; ; i++ {
		ch <- i * 2
	}
}

func pump2(ch chan int) {
	for i := 0; ; i++ {
		ch <- i + 5
	}
}

func suck(ch1, ch2 chan int) {
	for {
		select {
		case v := <-ch1:
			fmt.Printf("Received on channel 1: %d\n", v)
		case u := <-ch2:
			fmt.Printf("Received on channel 2: %d\n", u)
		}
	}
}

/*
在程序 goroutine_select.go 中有 2 个通道 ch1 和 ch2,三个协程 pump1()、pump2() 和 suck()。
这是一个典型的生产者消费者模式。
在无限循环中,ch1 和 ch2 通过 pump1() 和 pump2() 填充整数;
suck() 也是在无限循环中轮询输入的,
通过 select 语句获取 ch1 和 ch2 的整数并输出。
选择哪一个 case 取决于哪一个通道收到了信息。程序在 main 执行 1 秒后结束。

-----------------------------------
©著作权归作者所有:来自51CTO博客作者宇宙之一粟的原创作品,请联系作者获取转载授权,否则将追究法律责任
Go 语言入门很简单:使用 select 切换协程
https://blog.51cto.com/yuzhou1su/5416579
*/

标签:case,语句,协程,一抄,阻塞,break,表达式,Go,select
From: https://www.cnblogs.com/jianjiana/p/16975651.html

相关文章

  • 你应该知道的17个Golang包
    前言随着时间的推移,语言爱好者已经构建和共享了许多Go框架和库。这些包执行不同的功能,从开发微服务到制作discord机器人,一直到构建Web应用程序!在本文中,我将尝试让您熟......
  • MongoDB 聚合管道(Aggregation Pipeline)
    管道概念POSIX多线程的使用方式中,有一种很重要的方式-----流水线(亦称为“管道”)方式,“数据元素”流串行地被一组线程按顺序执行。它的使用架构可参考下图:以面向对象的思想......
  • itop3568开发板旋转uboot logo和内核logo
    修改设备树rk_android11.0_sdk/kernel/arch/arm64/boot/dts/rockchip/topeet_rk3568_lcds.dtsi文件。如果配套的屏幕是LVDS7寸屏幕或者LVDS10.1寸1024*600屏幕或......
  • go-dongle 0.2.1 版本发布,一个轻量级、语义化的 golang 编码解码、加密解密库
    dongle是一个轻量级、语义化、对开发者友好的Golang编码解码和加密解密库Dongle已被awesome-go收录,如果您觉得不错,请给个star吧github.com/golang-module/dong......
  • mongo的一些操作
    mongo语句mongo进入mongo//创建数据库并切换到此数据库useadmin//创建新用户=》在哪个库下就是选择创建哪个库的用户db.createUser({user:'linewell',pwd:'123456',......
  • 简单易懂的 Go 泛型使用和实现原理介绍
    原文:​​AgentleintroductiontogenericsinGo​​by​​DominikBraun​​万俊峰Kevin:我看了觉得文章非常简单易懂,就征求了作者同意,翻译出来给大家分享一下。本文是......
  • WeOpen Good 开源公益计划正式启动!聚开源智慧·行科技向善
    PART1缘起和初心8%、15%、20%……当看到这些数字,你第一时间会想到什么?少、不足一提,亦或是什么呢?1、我们生活的地球上,有超过70亿人口,其中10亿以上的人,也就是相当于总人口......
  • go 的形参
    注意记录一个go语言编程中,可能不小心忽略的一个点,当函数的出参如果是数组、结构体、字典类型时,是不需要声明的,可以直接使用。但是如果出参是指针类型,则必......
  • Django学习(第一天)
    搭建开发环境并创建第一个Django项目开发环境搭建一.安装pythonpython安装有两种方式直接安装或使用Anaconda开发环境管理工具安装我通常选择使用Anaconda来管理pytho......
  • golang error 使用
    前言在Go的编程中,error的使用场景数不胜数,主要就是用来处理各种异常情况.长久以来,我的使用方式都是这样的:err:=errors.New("fail")iferr!=nil{//dosom......