Golang 入门系列(六)理解Go中的协程(Goroutine)
2018-09-17 09:26
866 查看
前面讲的都是一些Go语言的基础知识,感兴趣的朋友可以先看看之前的文章。https://www.cnblogs.com/zhangweizhong/category/1275863.html。
今天就来讲讲go里面的高级功能,也是go语言重要的特性:Go协程(Goroutine)。
在函数调用前加上go关键字,这次调用就会在一个新的goroutine中并发执行。当被调用的函数返回时,这个goroutine也自动结束。听着感觉像C#中的Task。
需要注意的是,如果这个函数有返回值,那么这个返回值会被丢弃。
Go协程(Goroutine)之间通过信道(channel)进行通信,简单的说就是多个协程之间通信的管道。信道可以防止多个协程访问共享内存时发生资源争抢的问题。
1.定义
每个channel都有一个类型。此类型是允许信道传输的数据类型。channel是类型相关的,一个channel只能传递一种类型的值,这个类型需要在声明channel时指定。
2.声明
a.我们需要通过内置函数
下面的代码声明了一个信道:
b.与其他变量定义一样,快速声明也是定义信道的一种有效而简洁的方式:
c.创建一个带缓冲的channel
3.发送和接收数据
通过信道发送和接收数据的语法如下:
箭头的指向说明了数据是发送还是接收。
今天就来讲讲go里面的高级功能,也是go语言重要的特性:Go协程(Goroutine)。
什么是Go协程
Go协程(Goroutine)是与其他函数同时运行的函数。可以认为Go协程是轻量级的线程,由Go运行时来管理。在函数调用前加上go关键字,这次调用就会在一个新的goroutine中并发执行。当被调用的函数返回时,这个goroutine也自动结束。听着感觉像C#中的Task。
需要注意的是,如果这个函数有返回值,那么这个返回值会被丢弃。
Go协程(Goroutine)之间通过信道(channel)进行通信,简单的说就是多个协程之间通信的管道。信道可以防止多个协程访问共享内存时发生资源争抢的问题。
如何使用
packagemain import( "fmt" "time" ) funchello(){ fmt.Println("Helloworldgoroutine") } funcmain(){ gohello() time.Sleep(1*time.Second) fmt.Println("mainfunction") }
Channel(管道)
Channel(管道)可以被认为是协程之间通信的管道。与水流从管道的一端流向另一端一样,数据可以从信道的一端发送并在另一端接收。1.定义
每个channel都有一个类型。此类型是允许信道传输的数据类型。channel是类型相关的,一个channel只能传递一种类型的值,这个类型需要在声明channel时指定。
2.声明
a.我们需要通过内置函数
make来创建一个信道。
下面的代码声明了一个信道:
varchchanint
b.与其他变量定义一样,快速声明也是定义信道的一种有效而简洁的方式:
a:=make(chanint)
c.创建一个带缓冲的channel
c:=make(chanint,1024)
//从带缓冲的channel中读数据
fori:=rangec{
...
}
3.发送和接收数据
通过信道发送和接收数据的语法如下:
data:=<-a//从channela读取数据
a<-data//将数据写入到channela
箭头的指向说明了数据是发送还是接收。
完整例子
下面就直接说说,Goroutine和channel共同使用的完整例子:packagemain
import(
"fmt"
"time"
)
funcProducer(queuechan<-int){
fori:=0;i<10;i++{
queue<-i//写入
fmt.Println("create:",i)
}
}
funcConsumer(queue<-chanint){
fori:=0;i<10;i++{
v:=<-queue//读出
fmt.Println("receive:",v)
}
}
funcmain(){
queue:=make(chanint,88)
goProducer(queue)
goConsumer(queue)
time.Sleep(1*time.Second)
}
最后
以上,就简单的介绍了Go语言中的协程(Goroutine)和信道(channel)。这两个功能特性,是go语言中重要的特性。大家可以写写其他的例子,熟悉掌握。相关文章推荐
- Golang 入门系列(五)GO语言中的面向对象
- Golang 入门系列(三)Go语言基础知识汇总
- Golang 入门系列(二)学习Go语言需要注意的坑
- Golang 入门系列(一)Go环境搭建
- Golang 入门系列(四)如何理解interface接口
- Angular 4入门教程系列:2:从HelloWorld去理解Angular程序的组成和启动
- golang中runtime.Gosched()的理解
- 《Golang 入门系列四》golang的基本数据类型
- 深入理解SQLite3系列 (三)SQLite3入门
- 【 D3.js 入门系列 --- 7 】 理解 update, enter, exit 的使用
- golang语言并发与并行——goroutine和channel的详细理解
- golang技术随笔理解goroutine
- 简单测试一下go(golang) 和libtask 协程的切换效率
- 深入理解SQLite3系列 (三)SQLite3入门
- 【Go入门教程9】并发(goroutine,channels,Buffered Channels,Range和Close,Select,超时,runtime goroutine)
- go获取协程(goroutine)号
- 《Golang 入门系列三》golang的运算符
- go协程goroutine与Java多线程比较
- 进程、线程、轻量级进程、协程与 go 的 goroutine【转载+整理】
- 《Golang 入门系列二》fmt格式“占位符”