golang为什么设计channel?

如题所述

Channels,或称为Go的通道,是协程间通信的机制。它们允许一个协程向另一个协程发送数据。每个通道都需要指定数据类型,如 chan int。数据传输如同水在管道中流动。相对于传统线程通过共享内存通信,Go语言推崇使用通道而非共享内存。这意味着,Go语言通过数据传递实现共享内存,而非共享内存实现消息传递。

创建通道类型需遵循语法:var channel变量 chan channel类型。通道是引用类型,需配合make创建。创建语法:channel示例 := make(chan 数据类型)。实例如下:ch1 := make(chan int) 创建整数类型通道;ch2 := make(chan interface{}) 创建任意数据类型的空接口通道;ch3 := make(chan *Equip) 创建Equip指针类型的通道。

通道发送数据使用"<-"操作符。发送格式:channel变量 <- 值。发送数据类型需与通道元素类型一致。若接收方未接收,发送操作将阻塞所有goroutine,包括main的goroutine。此时运行会报错:fatal error: all goroutines are asleep - deadlock! 使用通道时需考虑死锁可能。如一个goroutine在通道上发送数据,其他goroutine应接收数据。若未发生,程序运行时将出现死锁。

通道接收数据同样使用"<-"操作符。接收格式:data := <-ch。接收时将阻塞,直至接收到数据并赋值给data变量。完整写法:data , ok := <-ch,data表示接收到的数据;ok表示是否接收到数据。忽略接收:<-ch,执行此语句将阻塞,目的不在于接收数据,而是阻塞goroutine。循环接收:配合关闭通道,使用普通for循环和for ... range语句循环接收多个元素。遍历通道,遍历结果即为接收数据,数据类型与通道数据类型相同。普通for循环接收,需有break循环条件;for range自动判断channel关闭,无需判断终止循环。

通道默认阻塞。当数据被发送到通道时,会阻塞直至有其他goroutine从该通道读取数据。读取数据时也会阻塞,直至其他goroutine将数据写入通道。这些特性有助于有效通信,无需使用其他语言的显式锁或条件变量。

关闭通道用于通知接受方数据传递完毕。发送方通常关闭通道。通过多重返回值判断通道是否关闭,若返回值为false,表示通道已被关闭。向关闭通道写入数据会报错:panic: send on closed channel。但从关闭后的通道取数据,返回数据默认值和false。

缓冲通道默认为非缓冲,读写即时阻塞。缓冲通道自带缓冲区,可暂存数据,缓冲区满时发生阻塞。对比非缓冲与缓冲通道,非缓冲通道打印结果为输入数据与接收数据交替,说明读写即时阻塞;缓冲通道部分打印数据输入完毕后打印接收数据,表明非缓冲区满时非阻塞。

生产者消费者模型可通过案例模拟,如下所示。通道默认双向读写,定向通道(单向通道)只读或只写。创建通道时,使用单向通道无意义,通常创建双向通道。将通道作为参数传递时使用单向通道。
温馨提示:答案为网友推荐,仅供参考
相似回答
大家正在搜