Hi,你们好,我是明哥。git
在本身学习 Golang 的这段时间里,我写了详细的学习笔记放在个人我的微信公众号 《Go编程时光》,对于 Go 语言,我也算是个初学者,所以写的东西应该会比较适合刚接触的同窗,若是你也是刚学习 Go 语言,不防关注一下,一块儿学习,一块儿成长。github
个人在线博客:http://golang.iswbm.com
个人 Github:github.com/iswbm/GolangCodingTimegolang
说到Go语言,不少没接触过它的人,对它的第一印象,必定是它从语言层面天生支持并发,很是方便,让开发者能快速写出高性能且易于理解的程序。编程
在 Python (为Py为例,主要是我比较熟悉,其余主流编程语言也相似)中,并发编程的门槛并不低,你要学习多进程,多线程,还要掌握各类支持并发的库 asyncio,aiohttp 等,同时你还要清楚它们之间的区别及优缺点,懂得在不一样的场景选择不一样的并发模式。数组
而 Golang 做为一门现代化的编程语言,它不须要你直面这些复杂的问题。在 Golang 里,你不须要学习如何建立进程池/线程池,也不须要知道什么状况下使用多线程,何时使用多进程。由于你没得选,也不须要选,它原生提供的 goroutine (也即协程)已经足够优秀,可以自动帮你处理好全部的事情,而你要作的只是执行它,就这么简单。微信
一个 goroutine 自己就是一个函数,当你直接调用时,它就是一个普通函数,若是你在调用前加一个关键字 go
,那你就开启了一个 goroutine。多线程
// 执行一个函数 func() // 开启一个协程执行这个函数 go func()
一个 Go 程序的入口一般是 main 函数,程序启动后,main 函数最早运行,咱们称之为 main goroutine
。并发
在 main 中或者其下调用的代码中才可使用 go + func()
的方法来启动协程。异步
main 的地位至关于主线程,当 main 函数执行完成后,这个线程也就终结了,其下的运行着的全部协程也无论代码是否是还在跑,也得乖乖退出。async
所以以下这段代码运行完,只会输出 hello, world
,而不会输出hello, go
(由于协程的建立须要时间,当 hello, world
打印后,协程还没来得及并执行)
import "fmt" func mytest() { fmt.Println("hello, go") } func main() { // 启动一个协程 go mytest() fmt.Println("hello, world") }
对于刚学习Go的协程同窗来讲,可使用 time.Sleep 来使 main 阻塞,使其余协程可以有机会运行彻底,但你要注意的是,这并非推荐的方式(后续咱们会学习其余更优雅的方式)。
当我在代码中加入一行 time.Sleep 输出就符合预期了。
import ( "fmt" "time" ) func mytest() { fmt.Println("hello, go") } func main() { go mytest() fmt.Println("hello, world") time.Sleep(time.Second) }
输出以下
hello, world hello, go
为了让你看到并发的效果,这里举个最简单的例子
import ( "fmt" "time" ) func mygo(name string) { for i := 0; i < 10; i++ { fmt.Printf("In goroutine %s\n", name) // 为了不第一个协程执行过快,观察不到并发的效果,加个休眠 time.Sleep(10 * time.Millisecond) } } func main() { go mygo("协程1号") // 第一个协程 go mygo("协程2号") // 第二个协程 time.Sleep(time.Second) }
输出以下,能够观察到两个协程就如两个线程同样,并发执行
In goroutine 协程2号 In goroutine 协程1号 In goroutine 协程1号 In goroutine 协程2号 In goroutine 协程2号 In goroutine 协程1号 In goroutine 协程1号 In goroutine 协程2号 In goroutine 协程1号 In goroutine 协程2号 In goroutine 协程1号 In goroutine 协程2号 In goroutine 协程1号 In goroutine 协程2号 In goroutine 协程1号 In goroutine 协程2号 In goroutine 协程1号 In goroutine 协程2号 In goroutine 协程1号 In goroutine 协程2号
经过以上简单的例子,是否是折服于Go的这种强大的并发特性,将同步代码转为异步代码,真的只要一个关键字就能够了,也不须要使用其余库,简单方便。
本篇只介绍了协程的简单使用,真正的并发程序仍是要结合 信道 (channel)来实现。关于信道的内容,将在下一篇文章中介绍。
系列导读
24. 超详细解读 Go Modules 前世此生及入门使用