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

作者 : admin 本文共1990个字,预计阅读时间需要5分钟 发布时间: 2024-06-6 共1人阅读

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通道消息:", mul_msg)
	case mul_sig := 接收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 := >>从通道中读取的值:", 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秒

本站无任何商业行为
个人在线分享 » golang通道(chan)选择(select)与关闭(close)使用示例
E-->