go语言并发编程 | 青训营笔记

73 阅读2分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 2 天

今天的内容是go语言并发机制的相关实现

并发编程

1、Goroutine

go语言的协程实现称为goroutine,每一个并发的执行单元叫作一个goroutine,在这之前首先需要了解一下线程和协程的关系,一个线程中可以运行多个协程,协程可以看作轻量级的线程,线程栈为MB级别,协程栈为KB级别。
实例代码(并发打印数字):
func hello(i int){
    println("hello goroutine : " + fmt.Sprint(i))
}
func HelloGoRoutine() {
    for i := 0; i < 5; i++ {
        go func(j int){
            hello(j)
        }(i)              
    }
    time.Sleep(time.Second)
}                          

2、CSP(communicating sequential processes)

CSP是一种并发编程模型,值会在不同goroutine中传递。相对应的传统并发模型则是我们熟悉的共享内存的方式,如临界区,通过加锁等操作实现并发编程,go语言提倡通过通信实现共享内存而非通过共享内存实现通信,使用内置的make函数创建channel:
ch := make(chan int)
ch := make(chan string, 3)

带缓存的channel在某些情景下能解决不带缓存channel导致的问题,比如同时向多个镜像站请求资源,由于接收方只接收最快的响应,如果此时使用不带缓存的channel将会导致除了率先响应的镜像站外,其他镜像站全部阻塞,从而导致bug出现,而使用对应数量带缓存的channel能避免这一问题。

3、sync

go语言中,基于互斥量,可以使用sync包中的方法实现锁,其中sync.Mutex为互斥锁,sync.RWMutex为读写锁,保证操作的执行顺序。同时sync包中还有Once方法可以实现懒初始化

4、WaitGroup(等待组)

Go语言中除了可以使用通道(channel)和互斥锁进行两个并发程序间的同步外,还可以使用等待组进 行多个任务的同步,WaitGroup包含Add,Done,Wait三个方法,通过计数器的增加减少实现对并发任务量的监控

总结

并发编程是每个语言设计时必须考虑的问题,也是程序设计能力进阶的必备技能,在学校中学习操作系统时,对于基于互斥量的并发程序同步已经有了比较清楚的了解,通过基于channel以及等待组的方法了解到了新的同步方式,对并发操作有了更多的认识