go的channel

go语言channel

go语言提供了goroutine来实现并发,go语言也提供了channel来实现并发事件之间的通信。
传统的编程语言通过共享内存来实现通信,当多个线程同时操作一个共享变量的时候,为了使程序达到预期的目的,可能会对变量加锁,这样就会使并发的程序等待,造成程序局部串行。而go的channel的设计理念是通过通信来共享内存。channel是一种特殊的类型,它遵循先进先出的原则,保证数据的收发顺序。go语言中的goroutine可以通过channel来通信。

chan的声明

import "fmt"

func main() {

	var chan1 chan int // 声明int类型的chan

	// chan是引用类型,必须舒适化后才能使用
	chan1 = make(chan int, 10)
	fmt.Println(chan1) // 0xc000082000
}

chan的声明有一点需要注意,那就是chan必须要用make初始化才能使用

chan的操作

package main

import "fmt"

func main() {

	var chan1 chan int // 声明int类型的chan

	// chan是引用类型,必须舒适化后才能使用
	chan1 = make(chan int, 10)

	// 向chan中传入10
	chan1 <- 10

	// 从chan中取值
	x := <-chan1
	fmt.Println(x)

	// 关闭chan
	close(chan1)

}

chan如果要使用也必须有一个缓冲区
当chan里面存的数据将缓冲区填满了,别的goroutine在想往chan中传输数据就得等待chan空余的位置,所以当创建一个chan的时候需要合理的给与chan的缓冲
关闭chan使用内置的close函数,关闭后的chan只能读值,不能存值
关闭已经关闭的chan会应发panic,关闭一个nil的chan也会应发panic

多个goroutine操作一个chan和chan的for循环

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

var chan1 chan interface{}

func add_to_chan(c chan interface{}, i int) {
	c <- i
	wg.Done()
}

func main() {

	// 过个goroutine往chan里添加数据
	chan1 = make(chan interface{}, 200)
	for i := 1; i < 100; i++ {
		wg.Add(1)
		go add_to_chan(chan1, i)
	}

	wg.Wait()

	defer close(chan1)
	// chan的for循环
	for i := range chan1 {
		fmt.Println(i)
	}

}

单向通道

有时候只想让一个通道只实现取值或者只存值,这时候后就需要用到单向通道了
单向通道一般用于函数的参数

func chan_demo(c1 <-chan interface{}, c2 chan<- interface{}) {
	
}

如上所示,c1只能为一个取值的通道,而c2是一个存值的通道

原文地址:https://www.cnblogs.com/ivy-blogs/p/12659430.html