Goroutine
은 Go
에서 사용하는 Coroutine
을 말합니다.
Go
에서 코루틴을 획기적으로 사용할 수 있게 하면서 붙인 이름입니다.
고루틴을 사용하기 위해서 단순히 go
키워드를 통해 고루틴 런타임으로 만들 수 있습니다.
func routine1() {
fmt.Println("routine1")
}
func routine2() {
fmt.Println("routine2")
}
func routine3() {
fmt.Println("routine3")
}
func main() {
go routine1()
go routine2()
go routine3()
fmt.Println("main routine")
time.Sleep(time.Second * 1)
}
// routine1
// main routine
// routine2
// routine3
이렇게 간단히 고루틴을 사용할 수 있습니다.
출력 순서는 실행시마다 다를 수 있으며,
main()
함수가 리턴되면 기존 루틴이 사라지기 때문에
모든 고루틴이 종료될 때까지 기다리기 위하여 time.Sleep()
의도적으로 기다리게 한 것입니다.
func routine1(waitGroup *sync.WaitGroup) {
fmt.Println("routine1")
waitGroup.Done()
}
func routine2(waitGroup *sync.WaitGroup) {
fmt.Println("routine2")
waitGroup.Done()
}
func routine3(waitGroup *sync.WaitGroup) {
fmt.Println("routine3")
waitGroup.Done()
}
func main() {
waitGroup := sync.WaitGroup{}
waitGroup.Add(3)
go routine1(&waitGroup)
go routine2(&waitGroup)
go routine3(&waitGroup)
fmt.Println("main routine")
waitGroup.Wait()
}
// routine1
// main routine
// routine2
// routine3
WaitGroup
은 고루틴의 루틴을 관리하는 주체이며,
이를 통해 고루틴이 종료될 때까지 기다리게 할 수 있습니다.
WiatGroup
에는 세 개의 메소드가 존재합니다.
- Add(): 관리할 고루틴을 추가합니다.
- Done(): 관리하던 고루틴의 종료를 알립니다.
- Wait(): 관리하던 고루틴이 모두 종료될 때까지 기다립니다.
만약
go routine3(&waitGroup)
구문이 없다면 마지막 고루틴이 실행되지 않아 종료 시그널이 오지 않기 때문에 데드락에 빠지게 됩니다.
또한 한 고루틴당Done()
메소드를 하나만 호출해야하는 것도 아니며, 고루틴이 아니어도Done()
메소드를 호출할 수 있습니다.
그리고Done()
메소드가Add()
메소드로 관리하게된 고루틴보다 많이 호출되어도 문제가 생기지는 않습니다.