美文网首页Golang开发轻松学GolangGo
Go的并发没有它,就像iphone没有网络一样

Go的并发没有它,就像iphone没有网络一样

作者: freelang | 来源:发表于2018-07-02 16:51 被阅读7次

Go的并发没有它,就像iphone没有网络一样

简介

Golang的并发属性是该语言的一个大杀器,说到并发就不能不提Channel,你可以把它看成一个管道,通过它并发核心单元就可以发送或者接收数据进行通讯。这篇文章来深入了解一下 channel。

channel 的设计是基于 CSP 模型的。CSP 是 Communicating Sequential Process 的简称,中文可以叫做通信顺序进程,是一种并发编程模型,由 Tony Hoare 于 1977 年提出。简单来说,CSP 模型由并发执行的实体(线程或者进程)所组成,实体之间通过发送消息进行通信,这里发送消息时使用的就是通道,或者叫 channel。CSP 模型的关键是关注 channel,而不关注发送消息的实体。Go 语言实现了 CSP 部分理论,goroutine 对应 CSP 中并发执行的实体,channel 也就对应着 CSP 中的 channel。

创建Channel

  • Go中的Channel使用chan作为关键字。

  • 无缓冲chan情况下,发送和接收会一直阻塞着,直到另一方准备好。这种方式可以用来在gororutine中进行同步,- 而需要使用锁或者条件变量。

  • 有缓冲chan,可以尽量避免阻塞,提高应用的性能,典型的以时间换空间。


aChan := make(chan int)  // 创建无缓冲chan
bChan := make(chan int, N) // 创建缓冲为N的chan</pre>

赋值和取值

从以下代码中看不出它的巨大作用,很正常,那是因为他们两条语句通常不在一起,例如:协程A发送数据,协程B接收数据


mchan <- value  // 发送值v到Channel ch中

value := <-mchan // 从Channel ch中接收数据,并将数据赋值给v



Select

Selsect是获取Channel中数据的最常用方式。

select 一定程度上可以类比于 linux 中的 IO 多路复用中的 select。后者相当于提供了对多个 IO 事件的统一管理,而 Golang 中的 select 相当于提供了对多个 channel 的统一管理。当然这只是 select 在 channel 上的一种使用方法。


func main(){

    ch1 := make(chan int, 1)

    ch2 := make(chan int, 1)

    select {

        case e1 := <-ch1:

        //如果ch1通道成功读取数据,则执行该case处理语句

            fmt.Printf("1th case is selected. e1=%v",e1)

        case e2 := <-ch2:

        //如果ch2通道成功读取数据,则执行该case处理语句

            fmt.Printf("2th case is selected. e2=%v",e2)

        default:

        //如果上面case都没有成功,则进入default处理流程

            fmt.Println("default!.")

    }

}

for...range

for …… range语句可以处理Channel。


    go func() {

        time.Sleep(1 * time.Hour)

    }()

    c := make(chan int)

    go func() {

        for i := 0; i < 10; i = i + 1 {

            c <- i

        }

        close(c)

    }()

    for i := range c {

        fmt.Println(i)

    }

    fmt.Println("Finished")

timeout

Select很重要的一个应用就是超时处理。 因为上面提供的demo,select语句就会一直阻塞着。这时候我们可能就需要一个超时操作,用来处理超时的情况。下面这个例子我们会在2秒后往channel c1中发送一个数据,但是Select设置为1秒超时,因此我们会打印出timeout 1,而不是result 1。


    c1 := make(chan string, 1)

    go func() {

        time.Sleep(time.Second * 2)

        c1 <- "result 1"

    }()

    select {

    case res := <-c1:

        fmt.Println(res)

    case <-time.After(time.Second * 1):

        fmt.Println("timeout 1")

    }

close

Go内建的close方法就可以用来关闭channel。但如果channel 已经被关闭,继续往它发送数据会导致panic: send on closed channel:


close(mChan)

推荐阅读
有,总比没有要好:Go依赖管理工具dep
工欲善其事,必先利其器 (Go开发工具)

相关文章

  • Go的并发没有它,就像iphone没有网络一样

    Go的并发没有它,就像iphone没有网络一样 简介 Golang的并发属性是该语言的一个大杀器,说到并发就不能不...

  • V语言学习笔记-21并发

    并发 还没有实现,语法基本跟go一样,也是使用go关键字,预计也是跟go一样的轻量级线程 目前如果使用go关键字,...

  • go基本语法

    一、总结 1、Go没有对象,没有继承多台,没有泛型,没有try/catch2、Go有接口,函数式编程,csp并发模...

  • 1.2 主要特性与发展的环境和影响因素

    Go 和 C++、Java 和 C# 一样属于 C 系。 Go 语言对于网络通信、并发和并行编程的极佳支持,从而更...

  • Golang 并发之一 ( go并发模型)

    如果必须选择 Go 的一项伟大功能,那么它必须是内置的并发模型。它不仅支持并发,而且使它变得更好。 Go Conc...

  • 【Golang】并发的异常处理

    go语言的并发实现起来很简单,只需要一个go关键字即可使函数并发,但是捕捉并发方法中的错误就没有那么方便了。本文总...

  • Golang 常见的并发模式

    常见的并发模式 Go语言最吸引人的地方是它内建的并发支持。Go语言并发体系的理论是C.A.R Hoare在1978...

  • Goroutine 是如何运行的

    在 Go 语言中,没有线程,只有 goroutine,这也是 Go 语言原生支持高并发的关键。 goroutine...

  • 瞅一眼就会使用GO的并发编程分享

    [TOC] GO的并发编程分享 之前我们分享了网络编程,今天我们来看看GO的并发编程分享,我们先来看看他是个啥 啥...

  • Go网络编程之并发聊天室

    并发聊天室 并发编程和网络编程是现今行业开发中常用的技术。Go语言强大的语法设定使得并发和网络编程都变的简洁而高效...

网友评论

    本文标题:Go的并发没有它,就像iphone没有网络一样

    本文链接:https://www.haomeiwen.com/subject/twyluftx.html