长安链 DApp 开发必学 Go 17:管道 Channel

63 阅读1分钟

我们都知道,进程间、线程间如果需要沟通合作,那么就需要进行通信。

因为每个执行流都有他自己的上下文,除非特殊情况,不能随便互相干涉,不然计算机就乱了套了。

协程也不例外,Go 提供了管道 Channel 来实现协程间的通信。

上代码:

package main

import "fmt"

func sum(s []int, c chan int) {
	sum := 0
	for _, v := range s {
		sum += v
	}
	c <- sum // send sum to c 用一个小箭头把计算结果发送到管道
}

func main() {
	s := []int{7, 2, 8, -9, 4, 0}

	c := make(chan int)  // 使用 make 初始化一个 int 型的管道
	go sum(s[:len(s)/2], c)  // 运行协程
	go sum(s[len(s)/2:], c)
	x, y := <-c, <-c // receive from c 从管道中获取数据 

	fmt.Println(x, y, x+y)
}

上述代码利用协程并发计算两个求和,并且通过管道传送到了主协程,并打印出来。

Go 的管道也支持缓存:

package main

import "fmt"

func main() {
	ch := make(chan int, 2)  // 初始化大小为 2 的管道
	ch <- 1                  // 塞入数据
	ch <- 2                  
	fmt.Println(<-ch)        // 获取数据
	fmt.Println(<-ch)
}

这里有个知识点,当一个协程向管道里塞入超过缓存大小的数据时,该协程会被阻塞(block),直到缓存空间被释放出来。

ok,下一章见~