Golang学习笔记:goroutine
1.goroutine
goroutine是go语言的并发体。在go语言里面能使用go关键字来实现并发。
go func()
1.1 概念介绍
goroutine本质上是协程,我刚刚学习的时候就粗略地认为goroutine是线程,直到最近才开始搞明白goroutine的基本概念。
并发
在很久以前,人们希望一个计算机(一个cpu)上能同时执行多项任务,让cpu在某段时间内进行分片,在某段很短时间内执行程序a,然后又迅速得切换到程序b去执行,让人们看起来就像是两个程序在同时进行,这就是并发。
进程
但是人们随之发现,cpu在切换程序的时候,如果不保存上一个程序的状态(也就是我们常说的context--上下文),直接切换下一个程序,就会丢失上一个程序的一系列状态,于是引入了进程这个概念,用以划分好程序运行时所需要的资源。因此进程就是一个程序运行时候的所需要的基本资源单位(也可以说是程序运行的一个实体)。
并行
如果一个电脑有多个cpu,每个cpu都有进程在运行,这就是并行。
用户态与内核态
为了防止用户程序做出一些危险的指令,如关机,更改系统变量,修改别的进程数据,系统分为两种运行状态,用户态以及内核态,用户态是我们的程序所在的状态,不能随便对内核的底层进行操作。如果我们需要使用内核的底层操作的时候,内核提供了一种调用内核的接口,我们调用这些接口也就是系统调用,在进行系统调用的时候,cpu会切换到内核态,才能执行内核的函数。
线程
人们又发现一个问题,cpu切换多个进程的时候,会花费不少的时间,因为切换进程需要切换到内核态,而每次调度需要内核态都需要读取用户态的数据,进程一旦多起来,cpu调度会消耗一大堆资源,因此引入了线程的概念,线程本身几乎不占有资源,他们共享进程里的资源,内核调度起来不会那么像进程切换那么耗费资源。
协程
但是线程还是需要内核去进行调度,切换起来也是需要把用户态的数据写入到内核态,也是需要耗费一定的计算机资源,那可以不可以将切换的调度改成我们自己控制的呢,答案是有的,协程就是把自己的调度算法交给程序(用户态)去进行管理,能以更小的资源去进行并发。
goruntine
goroutine就是一个协程例子,可以根据自身调度器进行调度,当某个gooutine调用了time.sleep方法或者channel,mutex阻塞时候,调度器会使其入睡,唤醒另一个goroutine,根本不需要进入到内核态。
2.通信
goroutine本质上是协程,可以理解为不受内核调度,而受go调度器管理的线程。goroutine之间可以通过channel进行通信,如下:
func main() {
c := make(chan string)
go func(){
c <- "hello"
}()
go func(){
word := <- c + " world"
fmt.Println(word)
}()
time.Sleep(1 * time.Second)
}
3.安全退出
goroutine只有在自身所在函数运行完毕,或者主函数运行完毕才会打断,因而上面的例子需要等待一秒,不然未执行完的goroutine会直接被打断。 如果我们并发的线程数量多了之后,我们不可能在main里面设置一个精确睡眠时间来评估所有的goroutine已经运行完毕然后退出。
这时候我们可以使用sync.WaitGroup来等待所有运行的goroutine运行结束后,再来退出main函数,主要原理是维护一个goroutine数量的计数器,每运行一个goroutine,计数器会加+1,运行结束后,计数器会-1,然后调用wait方法会一直阻塞,知道计数器为0,也就是当前运行的goroutine数量为0,实例如下:
func main() {
var n sync.WaitGroup
for i := 0; i < 20; i++ {
n.Add(1)
go func(i int, n *sync.WaitGroup) {
defer n.Done()
time.Sleep(1 * time.Second)
fmt.Printf("goroutine %d is running\n", i)
}(i, &n)
}
n.Wait()
}
Golang学习笔记:goroutine的更多相关文章
- golang学习笔记 --- goroutine
package main import ( "fmt" "io" "io/ioutil" "net/http" &quo ...
- golang学习笔记6 beego项目路由设置
golang学习笔记5 beego项目路由设置 前面我们已经创建了 beego 项目,而且我们也看到它已经运行起来了,那么是如何运行起来的呢?让我们从入口文件先分析起来吧: package main ...
- go语言,golang学习笔记2 web框架选择
go语言,golang学习笔记2 web框架选择 用什么go web框架比较好呢?能不能推荐个中文资料多的web框架呢? beego框架用的人最多,中文资料最多 首页 - beego: 简约 & ...
- golang学习笔记20 一道考察对并发多协程操作一个共享变量的面试题
golang学习笔记20 一道考察对并发多协程操作一个共享变量的面试题 下面这个程序运行的能num结果是什么? package main import ( "fmt" " ...
- golang学习笔记19 用Golang实现以太坊代币转账
golang学习笔记19 用Golang实现以太坊代币转账 在以太坊区块链中,我们称代币为Token,是以太坊区块链中每个人都可以任意发行的数字资产.并且它必须是遵循erc20标准的,至于erc20标 ...
- golang学习笔记18 用go语言编写移动端sdk和app开发gomobile
golang学习笔记18 用go语言编写移动端sdk和app开发gomobile gomobile的使用-用go语言编写移动端sdk和app开发https://blog.csdn.net/u01249 ...
- golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍
golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...
- golang学习笔记16 beego orm 数据库操作
golang学习笔记16 beego orm 数据库操作 beego ORM 是一个强大的 Go 语言 ORM 框架.她的灵感主要来自 Django ORM 和 SQLAlchemy. 目前该框架仍处 ...
- golang学习笔记14 golang substring 截取字符串
golang学习笔记14 golang substring 截取字符串golang 没有java那样的substring函数,但支持直接根据 index 截取字符串mystr := "hel ...
- golang学习笔记13 Golang 类型转换整理 go语言string、int、int64、float64、complex 互相转换
golang学习笔记13 Golang 类型转换整理 go语言string.int.int64.float64.complex 互相转换 #string到intint,err:=strconv.Ato ...
随机推荐
- 从PRISM开始学WPF(九)交互(完结)
0x07交互 Notification xaml: <Window x:Class="UsingPopupWindowAction.Views.MainWindow" xml ...
- Python内置函数(63)——property
英文文档: class property(fget=None, fset=None, fdel=None, doc=None) Return a property attribute. fget is ...
- GIT入门笔记(3)- git中的一些概念和原理
一.git管理过程中所处的4个阶段: 工作目录(workspace) 暂存区(index) 本地仓库(local repository) 远程仓库(remote repository) 二.工作目录+ ...
- 我的jquery validate 笔记
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF- ...
- JavaScript中的 原型 property 构造函数 和实例对象之间的关系
1 为什么要使用原型? /* * javascript当中 原型 prototype 对象 * * */ //首先引入 prototype的意义,为什么要使用这个对象 //先来写一个构造函数的面向对象 ...
- python开发:初识python
python简介 Python可以应用于众多领域,如:数据分析.组件集成.网络服务.图像处理.数值计算和科学计算等众多领域.目前业内几乎所有大中型互联网企业都在使用Python,如:Youtube.D ...
- wrapper x64 版本发布到centos
背景: 项目需要在spark任务提交服务器节点上自动提交任务到spark集群上.因此创建了一个固定时间监控任务项目,使用timer定时监控oracle数据库中是否有spark提交任务,如果有spark ...
- [论文阅读] Deep Residual Learning for Image Recognition(ResNet)
ResNet网络,本文获得2016 CVPR best paper,获得了ILSVRC2015的分类任务第一名. 本篇文章解决了深度神经网络中产生的退化问题(degradation problem). ...
- Spring基础复习
Spring IOC 使用注解实现Bean管理 注解类型: @Component:spring定义的通用注解,可用于注解任何bean @Repository, @Service,@Controller ...
- [LeetCode] Design Compressed String Iterator 设计压缩字符串的迭代器
Design and implement a data structure for a compressed string iterator. It should support the follow ...