并发编程通信方式之一-channel管道

1 概念-特性:go 语言channel 是引用类型,goroutine 间通过channel通信,遵循先入先出规则,保证收发数据顺序

2 创建方式:使用make 句柄创建,make(chan 数据类型)

3 向管道发送数据 , 格式如下:

test := make(chan interface{})  //此出不谈容量问题

test <- "hello"

test <- 0


* 发送需要了解的理论知识点:向管道发送数据,如无接受方,发送操作持续阻塞,用户态协成完全由实现方控制,所以需要实现方要写对等代码,有发送方,一定需要有接收方,即使我们的管道是含容量,容量堆满,也终究阻塞,所以有无容量,理论并不矛盾

* 收发不对等报错:fatal error: all goroutines are asleep - deadlock!

4 通过管道接受数据,所涉及知识点如下:

@非阻塞接收(使用该方式接收数据,语句不发生阻塞):

result, ok := <-ch   result 接受到的数据,没有数据为0值,引用类型,没有值默认0值, ok 是否接受到数据,bool类型,ch 管道变量

@阻塞接收(使用该方式接收数据,语句会发生阻塞):

result := <-ch  

@ 丢弃接受数据,一般为了实现收发对等

<-ch

5 管道数据遍历,格式如下:

    for data := range ch {

     }        

* c 通道不关闭,range 函数就不会结束,到没有接收到任何数据的时间,语句发生阻塞


6 实例代码(只需要关注管道收发业务即可,其它性能监控、数据竞争相关忽略):

package main

import (

  "fmt"

"log"

"net/http"

  _ "net/http/pprof"

"os"

"runtime"

"sync"

"sync/atomic"

)

var wg sync.WaitGroup

var timers int64

func main() {

  runtime.GOMAXPROCS(1)              // 限制 CPU 使用数,避免过载

  runtime.SetMutexProfileFraction(1) // 开启对锁调用的跟踪

  runtime.SetBlockProfileRate(1)    // 开启对阻塞操作的跟踪

  go func() {

      // 开启http服务

      if err := http.ListenAndServe(":6060", nil); err != nil {

        log.Fatal(err)

}

      os.Exit(0)

}()

  testChannel()

  select {}

}

func testChannel()  {

  caps := 200000

  ch := make(chan int,caps)

  wg.Add(caps)

  for i:= 0; i < caps; i++ {

      go func(a int) {

        defer wg.Done()

        atomic.AddInt64(&timers, 1)

        //原子安全读

        if atomic.LoadInt64(&timers) == int64(caps) {

            log.Println("close ch========")

            defer close(ch)

}

        log.Println("索引=",a)

        // 通过通道通知main的goroutine

        ch <- a

        fmt.Println("exit goroutine=",a)

      }(i)

}

  // 接收数据

  for data := range ch {

      fmt.Println("channel data = ",data)

}

  wg.Wait()

  fmt.Println("all done")

}



*  如有错欢迎留言批评指正 

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • goroutine sync.WaitGroup 其实 go 里面也提供了更简单的方式 —— 使用 sync.Wa...
    遇见你_17be阅读 615评论 0赞 0
  • # Goroutine多线程同步 Goroutine是Go语言特有的并发体,是一种轻量级的线程,由go关键字启动。...
    lixiande阅读 582评论 0赞 0
  • golang go和php的区别类型:go为编译性语言;php解释性语言错误:go的错误处理机制;php本身或者框...
    Impossible安徒生阅读 505评论 0赞 0
  • 前言 Golang在并发编程上有两大利器,分别是channel和goroutine,这篇文章我们先聊聊channe...
    即将秃头的Java程序员阅读 1,260评论 0赞 2
  • Channel是在goroutine之间同步的方式 定义 ChannelType = ( "chan" | "ch...
    集韵增广阅读 545评论 0赞 0

友情链接更多精彩内容