多线程一定记得防止在child开始之前主线程就关闭退出了

在涉及到多线程时,一般是需要main回收线程的退出状态,所以一般来说线程开始之后主线程是需要等待子线程运行结束的,在C里面有wait,在golang中有sync.WaitGroup来进行协调,今天在写go的时候遇到一个情况就是主线程开始之后立刻就退出了,而不是开启一个httpserver,仔细看了下代码发现了问题:因为需要频繁使用go func、WaitGroup.Add,WaitGroup.Done,所以写了个方法进行了封装如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func (s *Server)goruntine(f func(),wn string,num int){
for i := 0;i < num;i++{
log.Printf("Go routine name [%s_%d] start...\n",wn,num)
go func(){
s.wg.Add(1)
defer s.wg.Done()
f()
}()
}
}
func (s *Server)Run(){
s.init()
s.goruntine(s.communicate,"GoCommunicate",1)
//http.ListenAndServe(s.sc.LocalAddr + ":" + s.sc.LocalPort,nil)
s.http_wrap()
s.goruntine(s.runHttp,"GoHttpServer",1)
s.startup()
s.wg.Wait()
}

瞬间想起之前在写C的多线程的时候也是遇到了此类状况当时的原因是线程还没开始,父进程就exit了,仔细看了下这个代码,发现,goroutine这个函数并不会等待s.wg.Add结束之后才退出,所以发生这种情况的原因是在调用Wait之前就Add并没有来得及运行,造成了这种情况,解决的方法有两种:

  1. 将s.wg.Add放在go外面
  2. 在s.wg.Wait之前主动调用一次s.wg.Add