• 并发——无缓冲通道,带缓冲的通道,通道的多路复用,关闭通道


    1、无缓冲通道

    Go语言中无缓冲的通道(unbuffered channel)是指在接收前没有能力保存任何值的通道。这种类型的通道要求发送 goroutine 和接收 goroutine 同时准备好,才能完成发送和接收操作。如果两个 goroutine 没有同时准备好,通道会导致先执行发送或接收操作的 goroutine 阻塞等待。

    2、带缓冲的通道

    Go语言中有缓冲的通道(buffered channel)是一种在被接收前能存储一个或者多个值的通道。这种类型的通道并不强制要求 goroutine 之间必须同时完成发送和接收。通道会阻塞发送和接收动作的条件也会不同。只有在通道中没有要接收的值时,接收动作才会阻塞。只有在通道没有可用缓冲区容纳被发送的值时,发送动作才会阻塞。

    有缓冲的通道和无缓冲的通道之间的一个很大的不同:无缓冲的通道保证进行发送和接收的 goroutine 会在同一时间进行数据交换;有缓冲的通道没有这种保证。

    在无缓冲通道的基础上,为通道增加一个有限大小的存储空间形成带缓冲通道。带缓冲通道在发送时无需等待接收方接收即可完成发送过程,并且不会发生阻塞,只有当存储空间满时才会发生阻塞。同理,如果缓冲通道中有数据,接收时将不会发生阻塞,直到通道中没有数据可读时,通道将会再度阻塞。

    1)创建带缓冲的通道

    通道实例 := make(chan 通道类型, 缓冲大小)

    • 通道类型:和无缓冲通道用法一致,影响通道发送和接收的数据类型。
    • 缓冲大小:决定通道最多可以保存的元素数量。
    • 通道实例:被创建出的通道实例。

    3、通道的多路复用

    Go语言中提供了 select 关键字,可以同时响应多个通道的操作。由 select 开始一个新的选择块,每个选择条件由 case 语句来描述,每个 case 语句都必须是一个面向 channel 的操作,大致结构如下:

    select{
        case 操作1:
            响应操作1
        case 操作2:
            响应操作2
        …
        default:
            没有操作情况
    }

    • 操作1、操作2:包含通道收发语句。
    • 响应操作1、响应操作2:当操作发生时,会执行对应 case 的响应操作。
    • default:当没有任何操作时,默认执行 default 中的语句。

    4、关闭通道

    使用 close() 来关闭一个通道:close(ch)

    关闭的通道依然可以被访问,访问被关闭的通道将会发生一些问题。

    被关闭的通道不会被置为 nil。如果尝试对已经关闭的通道进行发送,将会触发宕机。

    从已经关闭的通道接收数据或者正在接收数据时,将会接收到通道类型的零值,然后停止阻塞并返回。

    示例:

    package main
    
    import "fmt"
    
    func main() {
    	ch := make(chan int, 2)
    	ch<-0
    	close(ch)
    	for  i := 0; i < 2 ; i++  {
    		v, ok := <-ch
    		fmt.Println(v, ok)
    	}
    }
    

      

  • 相关阅读:
    关于 Mercury_Lc 说明
    Java 对象和类
    Java int 与 Integer 区别
    Java Number & Math 类
    HTML | CSS | JavaScript 常见错误
    B. Heaters ( Codeforces Round #515 (Div. 3) )
    A. Vova and Train ( Codeforces Round #515 (Div. 3) )
    数据结构实验之排序四:寻找大富翁(SDUT 3401)
    JavaScript 与 Java
    A. The Fair Nut and Elevator (Codeforces Round #526 (Div. 2))
  • 原文地址:https://www.cnblogs.com/ACGame/p/12006246.html
Copyright © 2020-2023  润新知