Golang的select底层数据结构与特性

select关键字用于处理同时来自多个通道的数据。它的基本工作原理是“随机选择”满足条件的分支去执行。如果没有分支满足条件(即所有通道都无法读/写),select会阻塞,直到有分支满足条件。如果select包含default分支,当其他分支都不满足条件时,default分支会被执行。

Goselect底层使用了一种名为scase的结构体,表示一个select分支,包含了通道和对应的操作类型(发送或者接收)。同时,它还会使用一个名为hchan 的结构体来表示通道的内部结构。

以下是select的一些重要的特性:

  • 公平性:在Go语言中,select语言会随机选择一个可以运行的case执行,保证了每一个case都有公平的机会被执行,避免了饥饿问题。
  • 非阻塞:如果select中所有的case都无法运行,而且存在default分支,那么select就不会被阻塞,而是执行default分支。
  • 可用于时间操作select经常与time.After, time.Tick等函数一起使用,用于实现超时操作或者定时操作。
  • 可用于退出操作select经常和context一起使用,当收到context的取消信号时,可以安全地退出协程。
package main

import (
	"fmt"
	"time"
)

func selectExample(c1, c2 chan int, quit chan bool) {
	for {
		select {
		case v := <-c1:
			fmt.Println("Received from c1:", v)
		case v := <-c2:
			fmt.Println("Received from c2:", v)
		case <-quit:
			fmt.Println("Quit signal received. Exiting.")
			return
		default:
			fmt.Println("No data received.")
			time.Sleep(1 * time.Second) // 添加延迟以避免过度占用CPU
		}
	}
}

func main() {
	// 创建通道
	c1 := make(chan int)
	c2 := make(chan int)
	quit := make(chan bool)

	// 启动selectExample函数作为goroutine
	go selectExample(c1, c2, quit)

	// 启动发送数据到c1的goroutine
	go func() {
		for i := 0; i < 5; i++ {
			c1 <- i
			time.Sleep(1 * time.Second)
		}
	}()

	// 启动发送数据到c2的goroutine
	go func() {
		for i := 0; i < 5; i++ {
			c2 <- i + 10
			time.Sleep(2 * time.Second)
		}
	}()

	// 从主goroutine发送退出信号
	time.Sleep(10 * time.Second) // 等待足够时间以查看输出
	quit <- true
	fmt.Println("Sent quit signal and waiting to exit.")
}

最后给大家推荐一个LinuxC/C++高级架构系统教程的学习资源与课程,可以帮助你有方向、更细致地学习C/C++后端开发,具体内容请见 https://xxetb.xetslk.com/s/1o04uB

Golang 提供了一些底层数据结构,这些数据结构可以用于构建高效的程序。以下是一些常见的底层数据结构: 1. 数组(Arrays):在 Golang 中,数组是固定长度的数据结构,可以存储相同类型的元素。数组使用索引访问元素,具有快速的随机访问能力。 2. 切片(Slices):切片是一个动态长度的数组,可以根据需要进行扩展或收缩。切片是基于数组实现的,提供了更灵活的操作和更方便的使用。 3. 映射(Maps):映射是一种无序的键值对集合。它类似于字典或哈希表,通过键来访问值。Golang 的映射使用哈希表来实现,具有快速的查找和插入能力。 4. 链表(Linked Lists):链表是一种基本的数据结构,它由多个节点组成,每个节点包含一个值和一个指向下一个节点的指针。链表可以用于实现队列、栈和其他高级数据结构。 5. 栈(Stacks):栈是一种后进先出(LIFO)的数据结构,只能在栈顶进行插入和删除操作。Golang 中可以使用切片或链表实现栈。 6. 队列(Queues):队列是一种先进先出(FIFO)的数据结构,只能在队尾进行插入操作,在队头进行删除操作。Golang 中可以使用切片或链表实现队列。 7. 堆(Heaps):堆是一种特殊的二叉树,具有一些特定的性质。在 Golang 中,可以使用堆接口和堆包来实现最小堆或最大堆。 8. 树(Trees):树是一种非线性数据结构,由节点和边组成。树在计算机科学中有广泛的应用,如二叉树、AVL 树、红黑树等。 这些底层数据结构可以帮助开发者构建高效的程序,并在不同的应用场景中发挥作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值