Go并发原语/并发组件/go并发核心语法 之select

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013862108/article/details/88608480
select 语句是 将各种channel 绑定在一起的粘合剂; 连接各种组件在一起;
select 语句可以帮助安全地将channel 与诸如取消,超时,等待和默认值之类 的概念结合在一起。

与 switch 块不同, select 块中的case 语句没有测试顺序,如果没有满足任何条件,执行也不会失败。
如果所有channel 都没有准备好,则阻塞状态直到 。当一个channel准备好了,这个操作就会继续,它相应的语句就会执行。
func main() {
	start := time.Now()
	c := make(chan interface{})
	go func() {
		time.Sleep(5*time.Second)
		close(c)
	}()

	fmt.Println("Blocking on read ...")
	select {
		case <-c :
			fmt.Printf("Unblocked %v later.\n", time.Since(start))
	}

}
//Blocking on read ...
//Unblocked 5.00277253s later.
关于 select 一些问题?
当多个channel 有数据可供下游读取的时候会发生什么?
如没有 任何可用的channel 怎么办?
如果, 我们想做一些事情,但是没有可用的 channels 怎么办?


如果channel 同时可用会怎么样? 实验如下:

func main(){
	c1 := make(chan interface{}); close(c1)
	c2 := make(chan interface{}); close(c2)

	var c1Count, c2Count int
	for i := 1000; i>=0; i-- {
		select {
		case <- c1:
			c1Count++
			case <- c2:
				c2Count++
		}
	}
	fmt.Printf("c1Count: %d\nc2Count: %d\n", c1Count, c2Count)
}
//c1Count: 514
//c2Count: 487
第二个问题: 如果没有任何channel 可用,会发生什么?
第二个问题: 如果没有任何channel 可用,会发生什么?
如果没有可用的,但是你不希望 永远阻塞; 可能需要超时机制。
 */

func main(){
	var c <-chan int
	select {
		case <-c :
			case <-time.After(1 * time.Second):   //注释掉 就会 deadlock ,; 该channel 返回执行后的时间;
				fmt.Println("Time out.")
	}
}
第三个问题: 当没有可用channel 时, 我们需要做些什么?
第三个问题: 当没有可用channel 时, 我们需要做些什么?
当 select 语句中的所有channel都被阻塞时候, "select" 语句也允许你调用默认语句。
 */


func main(){
	start := time.Now()
	var c1, c2 <- chan int
	select {
		case <-c1:
			case <-c2:
	default:
		fmt.Printf("In default after %v\n\n", time.Since(start))
	}
}
//In default after 4.612µs
通常 ;会看到: default  和 for-select 循环一起使用,这允许goroutine在等待另一个goroutine上报结果的同时,可以继续执行自己的操作。
没有case 的select 将永远阻塞。
select{}

猜你喜欢

转载自blog.csdn.net/u013862108/article/details/88608480