GO语言学习笔记之channel

channel

  • 定义:channel是Go语言中的一个核心数据类型,可以将它看为管道或队列(FIFO)。并发核心单元通过它就可以发送或者接受数据进行通讯,这在一定程度上又进一步降低了编程的难度。

  • 目的:主要用来解决go程的同步问题以及协程之间的数据共享的问题。

    • goroutine运行在相同的地址空间,因此访问共享内存必须做好同步。goroutine奉行通过通信来共享内存,而不是共享内存来通信。
    • 引用类型channel可用于多个goroutine通信,其内部实现了同步,确保并发安全
  • 创建channel,channel的零值也是nil

    • 单向channel:var sendch chan <- int或 var reciveCh <- chan int或ch = make(chan <- int) ch = make(<- chan int)
    • 双向channel:var ch chan int、 make(chan Type)make(chan Type,capitity),Type代表在channel中传递的数据类型;容量代表channel缓冲区大小,0代表无缓冲channel,>0代表又缓冲channel。
    • 双向channel可以隐式转换为任意一种单向channel;但是单向channel不能转换为双向channel。
  • 复制或用于函数参数传递时,我们只是拷贝了一个channel引用

  • channel有两端,写段(传入端)chan <- 和读端(传出) <- chan;

    • 读端和写端必须同时满足条件,才能在chan上进行数据流动,否则阻塞。

    • channel应用于至少两个go程中,一个读另一个写。

    • 无缓冲channel:通道容量为0,具备同步的能力,读、写同步。

    • 有缓存channel:通道容量>0,len(chan):channel中剩余未读取数据个数,cap(chan):通道容量。缓冲区可以进行数据存储,存储至容量上限,阻塞。具备异步能力。不需要同时操作缓冲区。

    • 关闭channel:不再向对端发送信息,使用close(chan)关闭,一般是关闭写端

      • 无缓冲和有缓存channel都能关闭;
      • 数据不发送完,不关闭channel;
      • 已经关闭的channel,不能再往channel里写数据,会报错,报错信息:panic:send on closed channel,但是可以读数据(0),所以可以通过判断读到的数据是否为0来判断写端是否关闭;
      • 对端判断channel是否关闭代码示例如下:、
      if num,ok := <- ch;ok ==true{
        如果对端已经关闭,ok=false,则num无数据;
        如果对端没有关闭,ok=true,则num保存读到的数据;
      }
      //可以使用range
      for num := range ch {
      	打印出即可
      }
      

注意:每个进程启动时,系统会自动打开三个文件:标准输入、标准输出、标准错误。这三个分别对应三个文件:stdin,stdout,stderr。运行结束时,操作系统自动关闭三个文件。IO操作非常耗时。

  • 生产者消费者模型

    • 生产者:发送数据端
    • 消费者:接受数据段
    • 缓冲区
      • 作用
        • 解耦:降低生产者于消费者之间耦合度。
        • 并发:生产者消费者数量不对等时,能保持正常通信。
        • 缓存:生产者消费者速度不对等时,暂存数据。
  • 定时器Timer

    • NewTimer(duration)创建定时器,指定时长,定时到达后,系统会自动向定时器的成员C写系统当前时间。是对channel的写操作。
    • 结构定义
    type Timer struct{
    	C <- chan Time
    	r runtimeTimer
    }
    
    • 3种定时方法

      //1.sleep
      time.Sleep(time.Second)
      //2.Timer.C 定时器
      myTimer := time.NewTimer(time.Second*2)
      nowTime := <- myTime.C
      //3.2方法的封装
      nowtime := <- time.After(time.Second)
      
    • 定时器的停止和重置:

      • 停止:myTimer.stop()
      • 重置:myTime.Reset(duration)
  • 周期定时

    • 创建周期定时器,myTicker := time.NewTicker(duration)

      • 定时时长到达之后,系统会自动向Ticker的C种写入系统当前时间;
      • 并且,每隔一个定时时长之后,循环写入系统当前时间。
    • 结构定义

      type Ticker struct{
      	C <- chan Time
      	r runtimeTimer
      }
      
    • 在子go程种循环读取C,获取系统写入的时间。

你可能感兴趣的:(吾解,go语言,golang,go)