这是我参与「第三届青训营 -后端场」笔记创作活动的第2篇笔记
在上一篇笔记中,笔者简单介绍了go的基础语法,这篇笔记里,笔者将介绍课上所学的go的进阶语法。
Go的并发与Goroutines
Go的一大特点便是在基础语法上使用协程(Goroutines)支持了并发,由于协程位于内核态中,其栈的容量更小,也使得程序能够同时运行更多个协程。所以我们可以说,Goroutines是一种更加轻量化的线程。
Goroutines的使用方法
在需要调用的函数前面加上 go
func main() {
go hello()
time.Sleep(5 * time.Second)
fmt.Println("main")
}
func hello() {
fmt.Println("Hello world")
}
在上述代码中 ,main()函数中调用hello()函数时,在其前面加了go关键词,这意味着,go会运行一个新的Goroutines并将hello()交给这个新的Goroutines运行。
主协程
或许大家会注意到的,函数main()里有着一个延时函数sleep,这是为什么呢?这是因为,每个Goroutines在运行之初,就会创建一个Goroutines,这个Goroutines名叫主协程,之后所有的go关键词所创建的协程都是基于这个主协程的。所以如果Goroutines一旦执行完毕,整个程序都会终止,所以我们必须通过方法阻塞主协程,让其在最后运行完。
内存共享
我们在go中通常通过channel来共享内存。channel是一种基于CSP的思想,其希望通信共享内存,而非通过共享内存而通信。
Channel
channel通过以下代码形式声明并创建
make(chan 元素类型,缓冲区大小)
channelWithBuffer := make(chan int,2) //使用buffer的channel
channelWithoutBuffer := make(chan int)//不使用buffer的channel
channel可以使用箭头来操作
channel := make(chan int)
v := 1
channel <- v //发送值v到channel中
v := <- channel //用v接收channel中的值
并发安全
虽然go从底层就考虑了并发,实现并发不再需要依赖外部库,但是并发的安全问题依旧需要我们解决,我们有两个个方式解决并发安全问题。
- 锁 (sync.Mutex)
- WaitGroup (sync.WaitGroup)
锁通过互斥的机制来实现阻塞,而waitgroup通过计数器的方式阻塞。
以上就是go语言的基本语法了,也是我第一次课的笔记,希望能够帮到大家哦