掌握Golang中的select语句实现并发编程

 更新时间:2023年04月18日 10:02:58   作者:西直门三太子  
Golang中的select语句用于在多个通道间选择可读或可写的操作,并阻塞等待其中一个通道进行操作。可以用于实现超时控制、取消和中断操作等。同时,select语句支持default分支,用于在没有任何通道可操作时执行默认操作

序文

select 是用来配合channel使用的

空select

  • 没有内容的select 会阻塞
  • 没有内容是指,没有case,也没有default
  • 如果没有其它的任务指执行,将会触发死锁
package main
import (
    "fmt"
    "time"
)
/**
* 没有内容的select 会阻塞
* 没有内容是指,没有case,也没有default
* 如果没有其它的任务指执行,将会触发死锁
*/
func main() {
    go func() {
        time.Sleep(2 * time.Second)
        fmt.Println("没有内容的select 会阻塞")
    }()
    select {}
}

只有default的select

只有default的select 和串行化没有区别

package main
import "fmt"
/**
 只有default的select 和串行化没有区别
 */
func main() {
	go func() {
		fmt.Println("quick")
	}()
	select {
	default:
		fmt.Println("end")
	}
}

带 case 的 select

有case,有 default

  • 如果能匹配到case 就 执行 case
  • 匹配不到case,就执行default
  • 有 default,就代表了不会阻塞
package main
import (
	"fmt"
)
func main() {
	ch1 := make(chan int, 2)
	ch2 := make(chan int, 2)
	select {
	case v1 := <-ch1:
		fmt.Println(v1)
	case v2 := <-ch2:
		fmt.Println(v2)
	default:
		fmt.Println(22)
	}
}

package main
import (
	"fmt"
	"time"
)
func main() {
	ch1 := make(chan int, 2)
	ch2 := make(chan int, 2)
	go func() {
		ch1 <- 1
	}()
	time.Sleep(1 * time.Second)
	select {
	case v1 := <-ch1:
		fmt.Printf("get v1 chan value %d", v1)
	case v2 := <-ch2:
		fmt.Printf("get v1 chan value %d", v2)
	default:
		fmt.Println(22)
	}
}

有case,无default

会阻塞 一直等到case匹配上

package main
import (
	"fmt"
	"time"
)
func main() {
	ch1 := make(chan int, 2)
	ch2 := make(chan int, 2)
	fmt.Printf("start unix:%d \n", time.Now().Unix())
	go func() {
		time.Sleep(3 * time.Second)
		ch1 <- 1
	}()
	select {
	case v1 := <-ch1:
		fmt.Printf("case unix: %d \n", time.Now().Unix())
		fmt.Printf("get v1 chan value %d \n", v1)
	case v2 := <-ch2:
		fmt.Printf("get v1 chan value %d \n", v2)
	}
	fmt.Println("end")
}

select 只匹配一次,如果要进行 n > 1 的 匹配,使用 for + select

package main
import (
	"fmt"
	"time"
)
func main() {
	ch1 := make(chan int, 2)
	ch2 := make(chan int, 2)
	fmt.Printf("start unix:%d \n", time.Now().Unix())
	go func() {
		for {
			time.Sleep(1 * time.Second)
			ch1 <- 1
		}
	}()
	for {
		select {
		case v1 := <-ch1:
			fmt.Printf("case unix: %d \n", time.Now().Unix())
			fmt.Printf("get v1 chan value %d \n", v1)
		case v2 := <-ch2:
			fmt.Printf("get v1 chan value %d \n", v2)
		}
	}
}

匹配是无序的

package main
import (
	"fmt"
	"time"
)
func test() {
	ch1 := make(chan int)
	ch2 := make(chan int)
	go func() {
		ch1 <- 1
		close(ch1)
	}()
	go func() {
		time.Sleep(1 * time.Second)
		ch2 <- 1
		close(ch2)
	}()
	time.Sleep(2 * time.Second)
	// 如果有顺序,那么因该每次都是v1
	select {
	case v1 := <-ch1:
		fmt.Printf("case unix: %d \n", time.Now().Unix())
		fmt.Printf("get v1 chan value %d \n", v1)
	case v2 := <-ch2:
		fmt.Printf("case unix: %d \n", time.Now().Unix())
		fmt.Printf("get v2 chan value %d \n", v2)
	}
}
func main() {
	for i := 0; i < 10; i++ {
		test()
	}
}

到此这篇关于掌握Golang中的select语句实现并发编程的文章就介绍到这了,更多相关Golang中的select语句内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • golang 实现对Map进行键值自定义排序

    golang 实现对Map进行键值自定义排序

    这篇文章主要介绍了golang 实现对Map进行键值自定义排序,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • GO的基础知识扫盲注意事项

    GO的基础知识扫盲注意事项

    这篇文章主要介绍了GO的基础知识注意事项,本文是GO语言小白的扫盲文,主要讲解了go语言的基本知识,GO程序目录结构,GO程序包的导入与别名运用,GO内置关键字,GO注释方法需要的朋友可以参考下
    2022-12-12
  • golang 中 channel 的详细使用、使用注意事项及死锁问题解析

    golang 中 channel 的详细使用、使用注意事项及死锁问题解析

    这篇文章主要介绍了golang 中 channel 的详细使用、使用注意事项及死锁分析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • Go语言中函数的参数传递与调用的基本方法

    Go语言中函数的参数传递与调用的基本方法

    这篇文章主要介绍了Go语言中函数的参数传递与调用的基本方法,是golang入门学习中的基础知识,需要的朋友可以参考下
    2015-10-10
  • Gin框架限流实现示例

    Gin框架限流实现示例

    本文主要介绍了Gin框架限流实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • 详解在Go语言单元测试中如何解决Redis存储依赖问题

    详解在Go语言单元测试中如何解决Redis存储依赖问题

    在编写单元测试时,除了 MySQL 这个外部存储依赖,Redis 应该是另一个最为常见的外部存储依赖了,本文就来讲解下如何解决 Redis 外部依赖,文章通过代码示例介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • Golang正整数指定规则排序算法问题分析

    Golang正整数指定规则排序算法问题分析

    这篇文章主要介绍了Golang正整数指定规则排序算法问题,结合实例形式分析了Go语言排序算法操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2017-01-01
  • go中Excelize处理excel表实现带数据校验的文件导出

    go中Excelize处理excel表实现带数据校验的文件导出

    本文主要介绍了go中Excelize处理excel表实现带数据校验的文件导出,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • Go语言对字符串进行SHA1哈希运算的方法

    Go语言对字符串进行SHA1哈希运算的方法

    这篇文章主要介绍了Go语言对字符串进行SHA1哈希运算的方法,实例分析了Go语言针对字符串操作的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • Golang切片删除指定元素的三种方法对比

    Golang切片删除指定元素的三种方法对比

    Go语言并没有提供用于删除元素的语法或接口,而是通过利用切片本身的特性来删除元素—追加元素,这篇文章主要给大家介绍了关于Golang切片删除指定元素的三种方法,需要的朋友可以参考下
    2022-06-06

最新评论