go语言并发

摘要:
数据需要通过通道作为返回值从goroutine传输。声明通道类型的元素类型是在通道内传输的数据类型。使用通道发送数据格式。使用特殊运算符<通过信道发送数据的格式是:可以存储任何格式的数据传输将继续阻塞,直到数据被接收并发送到信道。当数据发送到信道时,信道用于接收数据。该信道还用于接收数据;因为当接收机未处理信道数据时,信道一次只能接收一个数据元素。
go语言并发

goroutine

goroutine格式

  • 为一个普通函数创建 goroutine 的写法如下:
go funcName(参数列表)
  • 为一个匿名函数创建goroutine的写法如下
go func(参数列表){
函数体
}(参数列表)

goroutine创建流程

  1. Go 程序从 main 包的 main() 函数开始,在程序启动时,运行时(runtime)会默认为 main() 函数创建一个默认的 goroutine。

  2. 在 main() 函数的 goroutine 中执行到 go funcName语句时,归属于 funcName函数的 goroutine 被创建。

  3. 此时,main() 继续执行,funcName函数开始在自己的 goroutine 中执行,两个 goroutine 通过 Go 程序的调度机制同时运作。

channel

  • 使用 go 关键字创建 goroutine 时,被调用函数的返回值会被忽略。

  • 如果需要在 goroutine 中返回数据,需要通过通道把数据从 goroutine 中作为返回值传出。

  • 在任何时候,同时只能有一个 goroutine 访问通道进行发送和获取数据。

声明通道类型

通道的元素类型就是在其内部传输的数据类型,声明如下:

var 通道变量 chan 通道类型
//通道类型:通道内的数据类型。
//通道变量:保存通道的变量。

chan 类型的空值是 nil,声明后需要配合 make 后才能使用。

创建通道

通道是引用类型,需要使用 make 进行创建,格式如下:

通道实例 := make(chan 数据类型)
//数据类型:通道内传输的元素类型。
//通道实例:通过make创建的通道句柄。

使用通道发送数据

  • 格式

通道的发送使用特殊的操作符<-,将数据通过通道发送的格式为:

通道变量 <- 值
//通道变量:通过make创建好的通道实例。
//值:可以是变量、常量、表达式或者函数返回值等。
//值的类型必须与ch通道的元素类型一致。如果值是空接口类型,可以存放任意格式的数据
  • 发送将持续阻塞直到数据被接收

把数据往通道中发送时,如果接收方一直都没有接收,那么发送操作将持续阻塞。

使用通道接收数据

通道接收同样使用 <- 操作符,通道接收有如下特性:

  1. 通道的收发操作在不同的两个 goroutine 间进行。

由于通道的数据在没有接收方处理时,数据发送方会持续阻塞,因此通道的接收必定在另外一个 goroutine 中进行。

  1. 接收将持续阻塞直到发送方发送数据。

如果接收方接收时,通道中没有发送方发送数据,接收方也会发生阻塞,直到发送方发送数据为止。

  1. 通道一次只能接收一个数据元素。

  2. 通道接收数据一共有下面4种写法

    1. 阻塞接收数据

      data := <-ch
      //执行该语句时将会阻塞,直到接收到数据并赋值给 data 变量。
      
    2. 非阻塞接收数据

      使用非阻塞方式从通道接收数据时,语句不会发生阻塞,格式如下:

      data, ok := <-ch
      //data:表示接收到的数据。未接收到数据时,data 为通道类型的零值。
      //ok:表示是否接收到数据
      

      非阻塞的通道接收方法可能造成高的 CPU 占用,因此使用非常少。如果需要实现接收超时检测,可以配合 select 和计时器 channel 进行。

    3. 接收任意数据,忽略接收的数据

    阻塞接收数据后,忽略从通道返回的数据,格式如下:

    <-ch
    

    执行该语句时将会发生阻塞,直到接收到数据,但接收到的数据会被忽略。这个方式实际上只是通过通道在 goroutine 间阻塞收发实现并发同步。例如因为所有 goroutine 在 main() 函数结束时会一同结束,可以在main函数结束前等待其他函数的goroutine

    1. 循环接收

      通道的数据接收可以借用 for range 语句进行多个元素的接收操作,格式如下:

      for data := range ch {}
      

      通道 ch 是可以进行遍历的,遍历的结果就是接收到的数据。数据类型就是通道的数据类型。通过for遍历获得的变量只有一个,即上面例子中的 data。

单向通道

Go 的通道可以在声明时约束其操作方向,如只发送或是只接收。这种被约束方向的通道被称做单向通道。

单向通道的声明

只能发送的通道类型为 chan<-,格式如下:

var 通道实例 chan<- 元素类型 

只能接收的通道类型为 <-chan,格式如下:

var 通道实例 <-chan 元素类型 

创建单向通道

通道实例 := make(<-chan 数据类型)
通道实例 := make(chan<- 数据类型)

带缓冲的通道Buffered Channels

在无缓冲通道的基础上,为通道增加一个有限大小的存储空间形成带缓冲通道。

带缓冲通道在发送时无需等待接收方接收即可完成发送过程,并且不会发生阻塞,只有当存储空间满时才会发生阻塞。

同理,如果缓冲通道中有数据,接收时将不会发生阻塞,直到通道中没有数据可读时,通道将会再度阻塞。

创建带缓冲的通道

通道实例 := make(chan 通道类型, 缓冲大小)
//缓冲大小:决定通道最多可以保存的元素数量。

go语言通道的多路复用

Go里面提供了一个关键字select监听channel上的数据流动。

select默认是阻塞的,只有当监听的channel中有发送或接收可以进行时才会运行,当多个channel都准备好的时候,select是随机的选择一个执行的。

在select里面还有default语法,select其实就是类似switch的功能,default就是当监听的channel都没有准备好的时候,默认执行的(select不再阻塞等待channel)。

select{
 case 操作1:
     响应操作1
 case 操作2:
     响应操作2
 …
 default:
     没有操作情况
}

go语言关闭通道后继续使用通道

格式

close(ch)

被关闭的通道不会被置为 nil。如果对已经关闭的通道进行发送,将会触发panic。

从已经关闭的通道接收数据或者正在接收数据时,将会接收到通道类型的零值,然后停止阻塞并返回。

[参考资料http://c.biancheng.net/view/99.html]

免责声明:文章转载自《go语言并发》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇cesium 中地图发生了平移,放缩,旋转等动作所要执行的动作关于远程调试下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Hive:ORC File Format存储格式详解

一、定义   ORC File,它的全名是Optimized Row Columnar (ORC) file,其实就是对RCFile做了一些优化。 据官方文档介绍,这种文件格式可以提供一种高效的方法来存储Hive数据。它的设计目标是来克服Hive其他格式的缺陷。 运用ORC File可以提高Hive的读、写以及处理数据的性能。和RCFile格式相比,ORC...

批量插入数据(基于Mybatis的实现-Oracle)

前言:做一个数据同步项目,要求:同步数据不丢失的情况下,提高插入性能。 项目DB框架:Mybatis。DataBase:Oracle。 ---------------------------------------------------------------------------- 批量插入数据方式: 一、Mybatis 全局设置批处理; 二、Myb...

窗口函数——数据分析

oracle的分析函数over 及开窗函数   转自:http://www.blogjava.net/loocky/archive/2007/11/13/160213.html     http://www.cnblogs.com/icebutterfly/archive/2009/08/05/1539657.html   一:分析函数overOracl...

Arduino I2C + 温湿度传感器HTS221

主要特性 HTS221是意法半导体(STMicroelectronics)生产的小体积、数字式温湿度传感器IC。该IC目前在官网仍处在“评估”状态。其主要特性: 工作电压:1.7~3.6V 数据输出频率(ODR)可设:1Hz ~ 12.5Hz 低功耗:2μA@1Hz ODR 温度精度:给出误差典型值+/-0.5°C, 15~40°C;但注明“Typic...

Wireshark——网络协议

一、ARP协议 ARP(Address Resolution Protocol)地址解析协议,将IP地址解析成MAC地址。 IP地址在OSI模型第三层,MAC地址在OSI第二层,彼此不直接通信; 在通过以太网发生IP数据包时,先封装第三层(32位IP地址)和第二层(48位MAC地址)的报头; 但由于发送数据包时只知道目标IP地址,不知道其Mac地址,且不能...

FTP协议的粗浅学习--利用wireshark抓包分析相关tcp连接

FTP相关文章: Linux上的ftp服务器 vsftpd 之配置满天飞--设置匿名用户访问(不弹出用户名密码框)以及其他用户可正常上传 ftp服务器Serv-U 设置允许自动创建不存在的目录     一、为什么写这个 昨天遇到个ftp相关的问题,关于ftp匿名访问的。花费了大量的脑细胞后,终于搞定了服务端的配置,现在客户端可以像下图一样,直接在浏览器输...