目标
errorchfinishChsingalChctrl+C
	for {
		select {
		case err = <- ErrorCh:
			fmt.Println("Error msg")
			return err
		case <- FinishCh:
			fmt.Println("Completed in success")
			return nil
		case s := <-c:
			fmt.Println("Stopped by signal received" + s.String())
			fmt.Println("Completed processing transactions")
			return nil
		}
	}
做法

之前的做法是在A,B,C中分别实现, 这样当A结束任务后,通知M结束进程。

func xxx(){
	if condition
		close FinishCh
}
问题
A, B, M, Cpanic: close of closed channel
改进

通过引入A,B,C共享的一个once函数来实现close chan的操作只执行一次

func xxx(){
	if condition
		once.Do(func() {
					close(finishCh)
		})
}