golang通道(chan)选择(select)与关闭(close)使用示例

1.通道选择

创建两个双向通道

c1 := make(chan string) //双向通道
c2 := make(chan string) //双向通道

向通道写入数据 

//协程1向通道1写数据
	go func() { c1 <- "hello world from c1" }()
	//协程2向通道2写数据
	go func() { c2 <- "hello world from c2" }()

遍历所有通道读取数据 

//遍历通道并选择对应通道操作
	for i := 0; i < 2; i++ {
		select {
		case recv1 := <-c1: //选择通道1
			fmt.Println("接收通道1数据:", recv1)
		case recv2 := <-c2: //选择通道2
			fmt.Println("接收通道2数据:", recv2)
		}
	}

通道超时处理:使用time.After为写入条件

//单通道超时操作
	go func() {
		time.Sleep(2 * time.Second) //休眠2秒,使通道超时有效
		c1 <- "===再次向通道c1写入数据==="
	}()
	select {
	case msg := <-c1:
		fmt.Println("接收通道1数据:", msg)
	case <-time.After(1 * time.Second): //通道操作超时
		fmt.Println("通道操作超时")
	}
非阻塞通道操作:
//非阻塞通道操作
	message := make(chan string)  //处理字符串的通道
	signalChan := make(chan bool) //处理布尔类型的通道
	//不阻塞处理message通道
	select {
	case msg := <-message: //接收
		fmt.Println("接收message通道消息:", msg)
	default:
		fmt.Println("message:没有要处理的消息")
	}

	//向通道发送消息
	msgSend := "这是向通道发送的消息"
	select {
	case message <- msgSend: //发送
		fmt.Println("成功向message通道发送消息", msgSend)
	default:
		fmt.Println("没有要向message通道发送的消息")
	}

	//不阻塞处理signalChan通道
	select {
	case msg := <-signalChan:
		fmt.Println("signalChan:处理消息:", msg)
	default:
		fmt.Println("signalChan:没有要处理的消息")
	}

	//向signalChan通道发送消息
	select {
	case signalChan <- true:
		fmt.Println("成功向通道signalChan发送消息", <-signalChan)
	default:
		fmt.Println("没有要向signalChan通道发送的消息")
	}

	go func() { message <- "msg for channel message" }()
	go func() { signalChan <- false }()

	fmt.Println(cap(message), len(message), cap(signalChan), len(signalChan))
	time.Sleep(1 * time.Second)
	//接收多通道消息,随机处理message/signalChan通道
	select {
	case mul_msg := <-message:
		fmt.Println("===>接收message通道消息:", mul_msg)
	case mul_sig := <-signalChan:
		fmt.Println("===>接收signalChan通道消息", mul_sig)
	default:
		fmt.Println("无通信活动")
	}

关闭通道处理:

//关闭通道测试
	jobs := make(chan int, 5) //通道缓存5条消息
	finish := make(chan bool) //任务完成状态

	//启动一个协程
	go func() {
		fmt.Println("协程已启动...")
		fmt.Println("jobs通道大小:", len(jobs), "容量:", cap(jobs))
		for {
			valueInChannel, getValueOK := <-jobs //取通道消息
			if getValueOK {
				fmt.Println(">>>从通道中读取的值:", valueInChannel)
			} else {
				fmt.Println("任务完成!") //调用close来关闭通道后,才会执行到这里
				finish <- true
				return
			}
		}
	}()

	//向通道插入5条消息
	for i := 0; i < 5; i++ {
		jobs <- (i + 1) * 5 //插入消息
	}
	fmt.Println("所有任务发送完成!!!")
	//关闭通道
	close(jobs)
	<-finish
	_, ok := <-jobs //再次读取通道数据
	if !ok {
		fmt.Println("所有任务已完成,通道无任何数据!", len(jobs), len(finish))
	}
	fmt.Println(ok)
	time.Sleep(time.Second * 1) //休眠1秒

相关推荐

  1. golang通道(chan)选择(select)关闭(close)使用示例

    2024-06-07 10:18:03       9 阅读
  2. golang定时器使用示例

    2024-06-07 10:18:03       11 阅读
  3. golang结构接口方法实现交互使用示例

    2024-06-07 10:18:03       10 阅读
  4. golang普通函数闭包函数使用示例

    2024-06-07 10:18:03       9 阅读
  5. GoLang - select

    2024-06-07 10:18:03       39 阅读
  6. Golang 协程通道

    2024-06-07 10:18:03       41 阅读
  7. golang接口/枚举/结构使用示例

    2024-06-07 10:18:03       8 阅读
  8. golang结构结构方法实现示例

    2024-06-07 10:18:03       9 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-06-07 10:18:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-07 10:18:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-07 10:18:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-07 10:18:03       18 阅读

热门阅读

  1. vue3中作用域插槽

    2024-06-07 10:18:03       9 阅读
  2. Stable Diffusion:多领域应用的创新引擎

    2024-06-07 10:18:03       10 阅读
  3. npm发布自己的插件包

    2024-06-07 10:18:03       9 阅读
  4. 从零手写实现 nginx-09-compress http 文件压缩

    2024-06-07 10:18:03       9 阅读
  5. 从零手写实现 nginx-10-sendfile 零拷贝 zero-copy

    2024-06-07 10:18:03       6 阅读
  6. 0.3 数字电视简介

    2024-06-07 10:18:03       9 阅读
  7. ubuntu使用 .deb 文件安装VScode

    2024-06-07 10:18:03       11 阅读
  8. springboot aop学习

    2024-06-07 10:18:03       7 阅读
  9. 史上最易懂的mysql锁 、mvvc分析

    2024-06-07 10:18:03       11 阅读