Channel概念

Channel 是Go中的一个核心类型,你可以把它看成一个管道Channel是引用类型,操作符是箭头 <- 

Channel 是 CSP 模式的具体实现,用于多个 goroutine 通讯。其内部实现了同步,确保并发安全。

Channel 是线程安全的先进先出,多个goroutine同时访问,不需要加锁,channel是有类型的,一个整数的channel只能存放整数。

Channel定义

第一种,channel声明

声明int类型的chan

var ch chan int

声明string类型的chan

var ch chan string

声明map类型chan

var ch chan map[int]string

第二种,使用make定义,无缓冲channel

var ch1 chan int = make(chan int)
var ch2 = make(chan int)
ch3 := make(chan int)

第三种,使用make定义,有缓冲channel

var ch1 chan int = make(chan int, )
var ch2 = make(chan int, )
ch3 := make(chan int, )

第四种,只读channel

var ch1 <-chan int
var ch2 <-chan int = make(<-chan int, )
var ch3 = make(<-chan int, )
ch4 := make(<-chan int, )

第五种,只写channel

var ch1 chan<- int
var ch2 chan<- int = make(chan<- int, )
var ch3 = make(chan<- int, )
ch4 := make(chan<- int, )

Channel特点

无缓冲的与有缓冲channel有着重大差别,那就是一个是同步的 一个是非同步的。

比如

无缓冲chan:ch1:=make(chan int)

有缓冲chan:ch2:=make(chan int,1)

无缓冲: ch1<-1 不仅仅是向 c1 通道放 1,而是一直要等有别的携程 <-ch1 接手了这个参数,那么ch1<-1才会继续下去,要不然就一直阻塞着。

有缓冲: ch2<-1 则不会阻塞,因为缓冲大小是1(其实是缓冲大小为0),只有当放第二个值的时候,第一个还没被人拿走,这时候才会阻塞。

缓冲区是内部属性,并非类型构成要素。

普通 channel 可以隐式转为只读channel或只写channel。

package main

var ch = make(chan int, )
var send chan<- int = ch
var recv <-chan int = ch func main() { }

只读channel或只写channel不能转为普通 channel。

package main

func main() {
var send chan<- int
var recv <-chan int ch1 := (chan int)(send)
ch2 := (chan int)(recv)
}

编译错误:

./main.go::: cannot convert send (type chan<- int) to type chan int
./main.go::: cannot convert recv (type <-chan int) to type chan int

Channel操作

使用内置函数 len() 返回未被读取的缓冲元素数量,使用内置函数 cap() 返回缓冲区大小。

package main

import "fmt"

func main() {
ch1 := make(chan int)
ch2 := make(chan int, ) ch2 <- fmt.Printf("ch1 缓冲元素数量:%v,缓冲区大小:%v\n", len(ch1), cap(ch1))
fmt.Printf("ch2 缓冲元素数量:%v,缓冲区大小:%v\n", len(ch2), cap(ch2))
}

运行结果:

ch1 缓冲元素数量:,缓冲区大小:
ch2 缓冲元素数量:,缓冲区大小:

channel 写入、读取操作:

package main

import "fmt"

func main() {
ch := make(chan int, )
// 写入chan
ch <- // 读取chan
value, ok := <-ch
if ok {
fmt.Printf("读取chan:%v\n", value)
} }

channel 关闭操作

1、使用内置函数 close() 进行关闭 chan。
2、chan关闭之后,for range遍历chan中已经存在的元素后结束。
3、没有使用for range的写法需要使用,val, ok := <- ch进行判断chan是否关闭。

package main

import "fmt"

func main() {
ch := make(chan int, ) ch <-
ch <-
ch <- close(ch)
for {
val, ok := <-ch
if ok == false {
fmt.Println("chan is closed")
break
}
fmt.Println(val)
}

注意:向已经关闭的 channel 发送数据会引发 panic 错误。

package main

func main() {
ch := make(chan int, )
close(ch)
ch <-
}

运行错误:

panic: send on closed channel

Go语言管道的更多相关文章

  1. C语言----管道

    一.管道的概念 管道是一种队列类型的数据结构,它的数据从一端输入,另一端输出.管道最常见的应用是连接两个进程的输入输出,即把一个进程的输出编程另一个进程的输入.shell中存在专门的管道运算符&quo ...

  2. Go语言目录

    为什么学习Go语言 第一章 环境搭建 Windows搭建Go语言环境 第二章 Go语言基础 Go语言介绍 Go语言命名 Go语言内置类型和函数 Go语言特殊函数介绍 Go语言运算符 第三章 Go语言程 ...

  3. 1、Go语言介绍

    一 Go语言介绍 Go 即Golang,是Google公司2009年11月正式对外公开的一门编程语言. Go是静态强类型语言,是区别于解析型语言的编译型语言. 解析型语言--源代码是先翻译为中间代码, ...

  4. java线程具体解释

    线程与进程的差别 (1)程序是一段静态的代码,进程是程序的一次动态执行过程.它是操作系统资源调度的基本单位.线程是比进程更小的执行单位.一个进程在其执行过程中,能够产生多个线程.所以又称线程为&quo ...

  5. spaCy 第二篇:语言模型

    spaCy处理文本的过程是模块化的,当调用nlp处理文本时,spaCy首先将文本标记化以生成Doc对象,然后,依次在几个不同的组件中处理Doc,这也称为处理管道.语言模型默认的处理管道依次是:tagg ...

  6. Go-简介-发展

    01-Go语言介绍 目录 Go语言介绍 Go语言特性 Go语言发展(版本/特性) Go语言应用 谁在用 应用领域 Go语言项目 Go语架构 Go语言发展前景 Go语言介绍 Go 即Golang,是Go ...

  7. 《Linux基础知识及命令》系列分享专栏

    <Linux基础知识及命令>系列分享专栏 本专题详细为大家讲解了Linux入门基础知识,思路清晰,简单易懂.本专题非常适合刚刚学习Linux的小白来学习,通过学习该专题会让你由入门达到中级 ...

  8. 1、Golang基础--Go简介、环境搭建、变量、常量与iota、函数与函数高级

    1 Go语言介绍 1 golang-->Go--->谷歌公司 2009年 golang:指go语言,指的go的sdk goland:软件,ide:集成开发环境 Java写的 2 Go是静态 ...

  9. Go语言中的管道(Channel)总结

    管道(Channel)是Go语言中比较重要的部分,经常在Go中的并发中使用.今天尝试对Go语言的管道来做以下总结.总结的形式采用问答式的方法,让答案更有目的性. Q1.管道是什么? 管道是Go语言在语 ...

随机推荐

  1. [GO] go使用etcd和watch方法进行实时的配置变更

    监控代码 package main import ( "go.etcd.io/etcd/clientv3" "time" "fmt" &qu ...

  2. [转]go中的main函数和init函数

    Go里面有两个保留的函数:init函数(能够应用于所有的package)和main函数(只能应用于package main).这两个函数在定义时不能有任何的参数和返回值.虽然一个package里面可以 ...

  3. jQuery中mouseover和mouseout冒泡产生闪烁问题

    问题:在jQuery中,对元素绑定mouseover和mouseout事件时,每次移入移出该元素和子元素时,都会触发事件,从而会出现闪动的现象. 原因:浏览器的冒泡行为. 解决方案: 使用mousee ...

  4. 8.7 正确使用索引(no)

    一 索引未命中 并不是说我们创建了索引就一定会加快查询速度,若想利用索引达到预想的提高查询速度的效果,我们在添加索引时,必须遵循以下问题 1 范围问题,或者说条件不明确,条件中出现这些符号或关键字:& ...

  5. CodeForces 518B Tanya and Postcard (题意,水题)

    题意:给定两个字符串,然后从第二个中找和第一个相同的,如果大小写相同,那么就是YAY,如果大小写不同,那就是WHOOPS.YAY要尽量多,其次WHOOPS也要尽量多. 析:这个题并不难,难在读题懂题意 ...

  6. 深入浅出 MappedByteBuffer

    前言 java io操作中通常采用BufferedReader,BufferedInputStream等带缓冲的IO类处理大文件,不过java nio中引入了一种基于MappedByteBuffer操 ...

  7. invoke方法

    主要是为了类反射,这样你可以在不知道具体的类的情况下,根据配置的字符串去调用一个类的方法.在灵活编程的时候非常有用.很多框架代码都是这样去实现的.但是一般的编程,你是不需要这样做的,因为类都是你自己写 ...

  8. access建立sql查询语句运行查询语句

    1.打开一个Access数据库文件 2.点击“创建”标签中的“查询设计”,会弹出一个“显示表”的对话框,点击“关闭”将其关闭 3.这时会有一个名为“查询*”的窗口,还不能输入SQL语句 4.点击左上角 ...

  9. 作业3:PSP记录耗时情况

    PSP2.1 Personal Software Process Stage Time planning 计划 10min Estimate 估计这个任务多久完成 150min Developing ...

  10. memory leak-----tomcat日志warn

    web应用借助于结构:spring mvc + quartz结构,部署到tomcat容器时,shutdown时的error信息: appears to have started a thread na ...