深度剖析channel

来源:互联网 时间:1970-01-01

##channel的用法channel是golang中很重要的概念,配合goroutine是golang能够方便实现并发编程的关键。channel其实就是传统语言的阻塞消息队列,可以用来做不同goroutine之间的消息传递,由于goroutine是轻量级的线程能够在语言层面调度,所以channel在golang中也常被用来同步goroutine。一般channel的声明形式为:var chanName chan ElementType 与一般的变量声明不同的地方仅仅是在类型之前加了chan关键字。ElementType指定这个channel所能传递的元素类型。定义一个channel也很简单,直接使用内置的函数make()即可:ch := make(chan int,bufferSize) //bufferSize为缓冲区的大小,可以不传递该值代表不带缓冲区的channel ###消息传递带有缓冲区的channel一般用来做不同goroutine之间的消息传递。最经典的解释莫过于生产者-消费者了。生产者向channel中写数据,如果channel缓冲区已满,则生产者会被阻塞直到消费者从缓冲区中消费数据后才能被唤醒。消费者从channel中读取数据,如果缓冲区中没有任何数据则消费者阻塞,直到生产者将数据写入才能被唤醒。假设我们有30个学生做作业,做完作业后由一个老师批改作业。用go怎么实现呢,我们首先定义一个带有缓冲区HomeWork chan(缓冲区的大小与学生数目相同,主要是为了防止学生提交作业时阻塞),学生做完作业向hwChan中发送数据,老师等待hwChan中有数据就取出学生作业然后批改。```const StudentNum = 30 type HomeWork struct { }function student(hwChan chan HomeWork) {//学生提交作业hwChan <- HomeWork{} }function teacher(hwChan chan HomeWork){//老师取出30个学生的作业批改for i:=0;i<StudentNum;i++ {hw := <- hwChan }}func main(){hwChan := make(chan HomeWork,30)//每个学生开启一个goroutine,学生单独做作业,做完作业提交到hwChan中即可for i:=0;i<StudentNum;i++ {go student(hwChan)}//老师开启一个goroutine,去批改学生作业go teacher(hwChan)time.Sleep(5*time.Second)}```**单向channel**student只需要向channel写数据,而不能从channel中读数据,但在func student(hwChan chan HomeWork) 这个函数中学生其实是有权限从channel中读数据,能限制这个函数只能取数据而不能写入数据吗?单向channel就是为了解决这个问题的:chan<- ElementType 表示只能向这个channel写数据<-chan T 表示只能从这个channel中读数据我们将student函数的参数变一下 func student(hwChan chan<- HomeWork)就可以将hwChan这个双向channel变成一个只能写的单向channel传到student函数中。同理teacher函数的参数变成 function teacher(hwChan <-chan HomeWork)也就规定了在teacher函数内只能从这个channel中读数据。###同步

相关阅读:
Top