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 ...
随机推荐
- Linq 巧用 Max,Sum
IList<, , , , , }; var sum1 = intList.Sum(s => { == ) { return s; } ; }); Console.WriteLine(&q ...
- C# 读取网页JSON数据
场景描述: 公司和别的系统需要对接,现在对方提供一个网址,数据都是json字符串,我需要对json数据进行处理. 提供的json数据如下格式 一.读取网址中的json数据 public string ...
- windbg分析Kernel32.dll导出表
写在前面的话: 继续上篇,在获得了Kernel32.dll基址的基础上,分析它的导出表结构: 对PE结构不太熟悉的同学,可以参考看雪论坛里的一篇帖子:https://bbs.pediy.com/thr ...
- 在Linux的Terminal中显示文本文件特定行的内容
假设要操纵的文本文件的文件名是 textFile现在想做的事情是在不以编辑模式打开文件的情况下在终端直接提取并输出指定文本文件的指定行的内容 在终端提取指定文本文件的指定行的内容 Tool Comma ...
- [BZOJ4011][HNOI2015] 落忆枫音(学习笔记) - 拓扑+DP
其实就是贴一下防止自己忘了,毕竟看了题解才做出来 Orz PoPoQQQ 原文链接 Description 背景太长了 给定一个DAG,和一对点(x, y), 在DAG中由x到y连一条有向边,求生成树 ...
- Hive:把一段包含中文的sql脚本粘贴到beeline client运行中文乱码
背景: 在做项目过程中不可能hive表中都是非中文字段.在最近做的项目中就遇到需要在beeline界面上执行查询脚本,但脚本中包含中文,正常一个脚本用文本写好后,粘贴到beeline窗口运行时,发现中 ...
- scrapy.Spider的属性和方法
scrapy.Spider的属性和方法 属性: name:spider的名称,要求唯一 allowed_domains:允许的域名,限制爬虫的范围 start_urls:初始urls custom_s ...
- [转]Python UnicodeEncodeError: 'gbk' codec can't encode character 解决方法
使用Python写文件的时候,或者将网络数据流写入到本地文件的时候,大部分情况下会遇到:UnicodeEncodeError: 'gbk' codec can't encode character ' ...
- 集合(list、set和map)区别
1.List,Set都是继承自Collection接口,Map则不是 2.List特点:元素有放入顺序,元素可重复:另外list支持for循环,也就是通过下标来遍历,也可以用迭代器, 3.Set特点: ...
- 在MySQL中使用子查询
子查询作为数据源 子查询生成的结果集包含行.列数据,因而非常适合将它与表一起包含在from子句的子查询里.例: SELECT d.dept_id, d.name, e_cnt.how_many num ...