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

Q1.管道是什么?
管道是Go语言在语言级别上提供的goroutine间的**通讯方式**,我们可以使用channel在多个goroutine之间传递消息。channel是**进程内**的通讯方式,是不支持跨进程通信的,如果需要进程间通讯的话,可以使用Socket等网络方式。

以上是管道的概念,下面我们就看下管道的语法。

Q2.管道的语法?

整个Go语言的语法都比较简洁,管道也不例外,其语法如下所示:

在此应当注意,管道是类型相关的,即一个管道只能传递一种类型的值。管道中的数据是先进先出的。

 // 声明方式,在此ElemType是指此管道所传递的类型
var chanName chan ElemType
// 声明一个传递类型为int的管道
var ch chan int
// 声明一个map,元素是bool型的channel
var m map[string] chan bool // 定义语法,定义需要使用内置函数make()即可,下面这行代码是声明+定义一个整型管道
ch := make(chan int)
// 事先定义好管道的size,下面这行代码定义管道的size为100
ch := make(chan int, 100) // 由管道中读写数据,<-操作符是与最左边的chan优先结合的
// 向管道中写入一个数据,在此需要注意:向管道中写入数据通常会导致程序阻塞,直到有
// 其他goroutine从这个管道中读取数据
ch<- value
// 读取数据,注意:如果管道中没有数据,那么从管道中读取数据会导致程序阻塞,直到有数据
value := <-ch // 单向管道
var ch1 chan<- float64 // 只能向里面写入float64的数据,不能读取
var ch2 <-chan int // 只能读取int型数据 // 关闭channel,直接调用close()即可
close(ch)
// 判断ch是否关闭,判断ok的值,如果是false,则说明已经关闭(关闭的话读取是不会阻塞的)
x, ok := <-ch

Q3.管道的使用场景?

在第一个问题中,我们已经知道管道可以做进程间通讯,Go中自带了对协程的支持(关键字go),而管道就是各个协程间通讯的一个方法。这里我们举些简单的小例子来说明一下管道如何在协程中使用。

 package main
import "fmt" func print() {
fmt.Println("Hello world")
} func main() {
for i := 0; i < 10; i++ {
go print()
}
}

上面的代码意思大致是:使用协程来并行输出10次 "Hello world", 但是大家运行上面代码的时候,会发现不会有输出。这是因为虽然使用go关键字进行了协程的创建,但是还没有等到执行的时候,main函数已经退出来了,进程已经关闭,所以起来的协程也不会被执行。

如果你有C相关的多线程经验时,可已经将协程改为线程,之后调用线程的join方法,让主线程等待子线程执行完毕后再退出。而在Go语言中,我们可以利用管道的写入阻塞和读取阻塞来完成类似线程join的行为。代码如下所示:

 package main
import "fmt" func print(ch chan int) {
fmt.Println("Hello world")
ch<- 1
} func main() {
chs := make([]chan int)
for i := 0; i < 10; i++ {
chs[i] = make(chan int)
go print(chs[i])
} for _, ch := range(chs){
<-ch
}
}

通过以上代码,我们就可以完成了并行输出10此Hello world 的效果。

有一个问题留给大家,如果将 print改为

 func print(ch chan int){
ch<- 1
fmt.Println("Hello world")
}

会打印出什么呢?

由于水平有限,难免会有错误,请大家指正。
谢谢。
[3/30]

Go语言中的管道(Channel)总结的更多相关文章

  1. R语言中的管道操作符 %>% %T>% %$% %<>%

    magrittr 包的官网 https://magrittr.tidyverse.org/ magrittr 包的 github 主页 https://github.com/tidyverse/mag ...

  2. Go语言的管道Channel用法

    本文实例讲述了Go语言的管道Channel用法.分享给大家供大家参考.具体分析如下: channel 是有类型的管道,可以用 channel 操作符 <- 对其发送或者接收值. ch <- ...

  3. Go语言中的有缓冲channel和无缓冲channel区别

    Go语言中的有缓冲channel和无缓冲channel区别 结论 ch1:=make(chan int)// 无缓冲 ch2:=make(chan int,1)// 有缓冲 无缓冲: 当向ch1中存值 ...

  4. Go 语言中的 new() 和 make()的区别

    本文是看了文章之后的心得. 在此感谢. 概述 Go 语言中的 new 和 make 一直是新手比较容易混淆的东西,咋一看很相似.不过解释两者之间的不同也非常容易. 他们所做的事情,和应用的类型也不相同 ...

  5. go语言之并发编程 channel

    前面介绍了goroutine的用法,如果有多个goroutine的话相互之间是如何传递数据和通信的呢.在C语言或者JAVA中,传输的方法包括共享内存,管道,信号.而在Go语言中,有了更方便的方法,就是 ...

  6. 【转载】如何在C语言中调用shell命令

    转载自:http://blog.csdn.net/chdhust/article/details/7951576 如何在C语言中调用shell命令 在linux操作系统中,很多shell命令使用起来非 ...

  7. Core 1.0中的管道-中间件模式

    ASP.NET Core 1.0中的管道-中间件模式 SP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middlewar ...

  8. GO语言中的几个关键思想

    GO语言的设计理念与C++,Java,Python之流大相径庭. 一.没有函数重载 GO语言里面没有函数重载,Java.C#.C++三位大牛都是支持函数重载的,Python虽然不支持函数重载,但是支持 ...

  9. 一个I/O线程可以并发处理N个客户端连接和读写操作 I/O复用模型 基于Buf操作NIO可以读取任意位置的数据 Channel中读取数据到Buffer中或将数据 Buffer 中写入到 Channel 事件驱动消息通知观察者模式

    Tomcat那些事儿 https://mp.weixin.qq.com/s?__biz=MzI3MTEwODc5Ng==&mid=2650860016&idx=2&sn=549 ...

随机推荐

  1. flume-agent实例

    flume    多种适配,多样化的数据收集    核心概念        event:一条消息        client:访问者        agent:            重要组件Sour ...

  2. PHP各版本之间差异

    PHP5.3 __toString 魔术方法不再接受参数. 魔术方法 __get, __set, __isset, __unset, and __call 应该总是公共的(public)且不能是静态的 ...

  3. javascript--瀑布流

    简单瀑布流代码实现 html代码例如以下 <!DOCTYPE html> <html> <head> <meta http-equiv="Conte ...

  4. Linux输出重定向

  5. javascript正则

      <script type="text/javascript"> //去除两边空格,如果要去除所有空格,使用/\s*即可/ String.prototype.trim ...

  6. 用ueditor上传图片、文件等到七牛云存储

    ueditor上传文件,是用数据流的形式上传的. 而七牛云存储官方文档中,只提供了文件路径上传的方式. 但是,仅仅是在官方文档中写了这一种方式. 事实上,利用VS的对象管理器,打开Qiniu的dll, ...

  7. sqlserver中的锁与事务

    以下内容整理自: SQL Server中的锁 SQLSERVER中的元数据锁 SQLSERVER中的锁资源类型 浅谈sqlserver中的事务和锁 锁的分类 1.从数据库角度 独占锁(排它锁 X) 独 ...

  8. Html.Action和Html.RederAction来创建子视图

    1. 父视图和子视图 父视图是包含了调用返回子视图的动作方法的视图. 父视图包含大部分用于呈现页面的HTML.子视图仅包含用于展示视图某部分的必须的标记. 例如,一个子视图创建一个列表,视图可能仅仅包 ...

  9. (转)JSON 之FastJson解析

    一.阿里巴巴FastJson是一个Json处理工具包,包括“序列化”和“反序列化”两部分,它具备如下特征:速度最快,测试表明,fastjson具有极快的性能,超越任其他的Java Json parse ...

  10. RxJava漫谈-RxAndroid使用

    RxJava在github上的地址:https://github.com/ReactiveX/RxJava RxAndroid在github上的地址:https://github.com/Reacti ...