Go语言入门学习之Channel通道详解_第1页
Go语言入门学习之Channel通道详解_第2页
Go语言入门学习之Channel通道详解_第3页
Go语言入门学习之Channel通道详解_第4页
Go语言入门学习之Channel通道详解_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第Go语言入门学习之Channel通道详解目录前言通道的声明通道的初始化发送和接收数据通道的关闭通道的容量与长度缓冲通道与无缓冲通道双向通道和单向通道遍历通道fibonacci数列参考文章:总结

前言

不同于传统的多线程并发模型使用共享内存来实现线程间通信的方式,go是通过channel进行协程(goroutine)之间的通信来实现数据共享。

channel,就是一个管道,可以想像成Go协程之间通信的管道。它是一种队列式的数据结构,遵循先入先出的规则。

通道的声明

每个通道都只能传递一种数据类型的数据,声明时需要指定通道的类型。chanType表示Type类型的通道。通道的零值为nil。

varchannel_namechanchannel_types

varstrchanstring

通道的初始化

声明完通道后,通道的值为nil,不能直接使用,使用make函数对通道进行初始化操作。

channel_name=make(chanchannel_type)

str=make(chanstring)

或者

str:=make(chanstring)

发送和接收数据

发送数据,把data数据发送到channel_name通道中。

channel_name-data

接收数据,从channel_name通道中接收数据到value。

value:=-channel_name

funcPrintFunc(cchanstring){

c-"往通道里面传数据"

funcmain(){

str:=make(chanstring)

fmt.Println("start")

goPrintFunc(str)

result:=-str

fmt.Println(result)

fmt.Println("end")

}

发送与接收默认是阻塞的。如果从通道接收数据没接收完主协程是不会继续执行下去的。当把数据发送到通道时,会在发送数据的语句处发生阻塞,直到有其它协程从通道读取到数据,才会解除阻塞。与此类似,当读取通道的数据时,如果没有其它的协程把数据写入到这个通道,那么读取过程就会一直阻塞着。

通道的关闭

对于一个已经使用完毕的通道,我们要将其进行关闭。对于一个已经关闭的通道如果再次关闭会导致报错。

close(channel_name)

可以在接收数据时,判断通道是否已经关闭,从通道读取数据返回的第二个值表示通道是否没被关闭,如果已经关闭,返回值为false;如果还未关闭,返回值为true。

value,ok:=-channel_name

通道的容量与长度

通道可以设置缓冲区,通过make的第二个参数指定缓冲区大小

ch:=make(chanint,100)

0:通道中不能存放数据,在发送数据时,必须要求立马接收,否则会报错。此时的通道称之为无缓冲通道。1:通道只能缓存一个数据,若通道中已有一个数据,此时再往里发送数据,会造成程序阻塞。利用这点可以利用通道来做锁。大于1:通道中可以存放多个数据,可以用于多个协程之间的通信管道,共享资源。

通过cap函数和len函数获取通道的容量和长度。

funcmain(){

//创建一个通道

c:=make(chanint,5)

fmt.Println("初始化:")

fmt.Println("cap:",cap(c))

fmt.Println("len:",len(c))

c-1

c-2

c-3

fmt.Println("传入数据:")

fmt.Println("cap:",cap(c))

fmt.Println("len:",len(c))

fmt.Println("取出一个数:")

fmt.Println("cap:",cap(c))

fmt.Println("len:",len(c))

}

缓冲通道与无缓冲通道

带缓冲区的通道允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。

不过由于缓冲区的大小是有限的,所以还是必须有接收端来接收数据的,否则缓冲区一满,数据发送端就无法再发送数据了。

通道不带缓冲,发送方会阻塞直到接收方从通道中接收了值。如果通道带缓冲,发送方则会阻塞直到发送的值被拷贝到缓冲区内;如果缓冲区已满,则意味着需要等待直到某个接收方获取到一个值。接收方在有值可以接收之前会一直阻塞。

c:=make(chanint)

//或者

c:=make(chanint,0)

缓冲通道允许通道里存储一个或多个数据,设置缓冲区后,发送端和接收端可以处于异步的状态。

c:=make(chanint,3)

双向通道和单向通道

双向通道:既可以发送数据也可以接收数据

funcmain(){

//创建一个通道

c:=make(chanint)

//发送数据

gofunc(){

fmt.Println("send:1")

c-1

//接收数据

gofunc(){

n:=-c

fmt.Println("receive:",n)

//主协程休眠

time.Sleep(time.Millisecond)

}

单向通道:只能发送或者接收数据。具体细分为只读通道和只写通道。

-chan表示只读通道:

//定义只读通道

c:=make(chanstring)

//定义类型

typeReceiver=-chanstring

varreceiverReceiver=c

//或者简单写成下面的形式

typeReceiver=-chanint

receiver:=make(Receiver)

chan-表示只写通道:

//定义只写通道

c:=make(chanint)

//定义类型

typeSender=chan-int

varsenderSender=c

//或者简单写成下面的形式

typeSender=chan-int

sender:=make(Sender)

packagemain

import(

"fmt"

"time"

//Sender只写通道类型

typeSender=chan-string

//Receiver只读通道类型

typeReceiver=-chanstring

funcmain(){

//创建一个双向通道

varch=make(chanstring)

//开启一个协程

gofunc(){

//只写通道

varsenderSender=ch

fmt.Println("writeonlystart:")

sender-"Go"

//开启一个协程

gofunc(){

//只读通道

varreceiverReceiver=ch

message:=-receiver

fmt.Println("readonlystart:",message)

time.Sleep(time.Millisecond)

}

遍历通道

使用forrange循环可以遍历通道,但在遍历时要确保通道是处于关闭状态,否则循环会被阻塞。

packagemain

import(

"fmt"

funcloopPrint(cchanint){

fori:=0;ii++{

c-i

//记得要关闭通道

//否则主协程遍历完不会结束,而会阻塞

close(c)

funcmain(){

//创建一个通道

varch2=make(chanint,5)

goloopPrint(ch2)

forv:=rangech2{

fmt.Println(v)

}

fibonacci数列

packagemain

import(

"fmt"

funcfibonacci(nint,cchanint){

x,y:=0,1

fori:=0;ii++{

c-x

x,y=y,x+y

close(c)

funcmain(){

c:=make(chanint,10)

gofibonacci(cap(c),c)

//range函数遍历每个从通道接收到的数据,因为c在发送完1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论