这是我参与「第四届青训营 」笔记创作活动的第5天
由于我们设计的大项目中NameNode是需要与DataNode进行交互的,但是这些交互过程又不要求顺序性,因此我们决定将代码设计为并发的访问DataNode。
waitgroup简介
waitgroup是go sync包中的并发设计之一,它使用起来十分简单。 首先,在waitgroup中有3个方法,第一个是add,它传入一个int型参数,表示要开启多少个goroutine数量,第二个方法是done,顾名思义,done就表示这件任务完成了,因此它需要写在gorouine里面。第三个方法就是wait,因为新开的goroutine与其原本所在goroutine是并行执行的,因此,如果不使用某种方式来让原goroutine等待的话,那么当开出去的那个goroutine执行完毕返回时,就会发生一些预料之外的事情,比如找不到原来的goroutine了。因此就有了这3个方法来同步goroutine之间的执行。
waitgroup的原理
WaitGroup它的内部维护了一个计数信号量counter,可以用来记录并维护运行中的 goroutine数目。在一开始,waitgroup中的add方法会将counter置为goroutine的数量,在goroutine运行过程中,如果 WaitGroup的值大于 0,Wait 方法就会阻塞,这就意味着原goroutine会等待并发出去的goroutine执行完毕,从而实习了同步。当开出去的goroutine中的done方法被调用时,它会将counter自己减,每执行完毕一个goroutine,counter就自减一,wait方法会一直监听counter是否为0,当counter为0的时候,就说明所有的goroutine都执行完了,那么主goroutine就可以退出了,这样就不会丢失goroutine之间的信息。
个人认为waitgroup同步使用起来要简单很多,当然这也得益于go并发抽象的设计比较简单。