본문 바로가기

IT/Go 언어 (Golang)

[Golang] Go Routine (고 루틴) - Golang의 꽃 [기본]

반응형

Golang에는 Go Routine(이하 "고루틴")으로 불리는 동시성 예약어가 있다.

즉, main 함수를 돌리면서 순차적이 아니라 익명함수나 함수를 동시에 실행시킬 수 있다는 뜻이다.

 

바로 아래 예제를 살펴보자.

// Go Routine

package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	var cnt int = 10
	var n int = 1
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(n int) {
			defer wg.Done()
			cnt--
			switch n {
			case 1:
				fmt.Println("I'm", n, "st Go Routine! :D and now cnt is:", cnt)
			case 2:
				fmt.Println("I'm", n, "nd Go Routine! :D and now cnt is:", cnt)
			case 3:
				fmt.Println("I'm", n, "rd Go Routine! :D and now cnt is:", cnt)
			default:
				fmt.Println("I'm", n, "th Go Routine! :D and now cnt is:", cnt)
			}
		}(n)
		n++
	}
	wg.Wait()
	fmt.Println("cnt is now: ", cnt)
}

위 소스 코드를 보면, 단순히 cnt라는 변수를 10에서 0까지 1씩 빼는 역할을 한다.

하지만 우리는 중요한 것을 아래 소스 코드 실행 결과에서 알 수 있다.

I'm 3 rd Go Routine! :D and now cnt is: 3
I'm 5 th Go Routine! :D and now cnt is: 5
I'm 1 st Go Routine! :D and now cnt is: 9
I'm 2 nd Go Routine! :D and now cnt is: 8
I'm 6 th Go Routine! :D and now cnt is: 7
I'm 4 th Go Routine! :D and now cnt is: 6
I'm 8 th Go Routine! :D and now cnt is: 2
I'm 9 th Go Routine! :D and now cnt is: 1
I'm 7 th Go Routine! :D and now cnt is: 0
I'm 10 th Go Routine! :D and now cnt is: 4
cnt is now:  0

위는 필자가 해당 소스 코드를 실행시켰을 때 얻은 결과였다.

사람마다 결과는 다 다를 수 있다. 오히려 필자와 같기가 더 힘들 것이다.

필자도 소스 코드를 실행할 때마다 결과가 달라진다.

 

원래 전통적인 절차지향 언어에서는, 똑같은 기능을(cnt를 10에서 0까지 1씩 뺌) 하는 소스 코드에서 다음과 같은 실행 결과를 냈을 것이다.

I'm 1 st Go Routine! :D and now cnt is: 9
I'm 2 nd Go Routine! :D and now cnt is: 8
I'm 3 rd Go Routine! :D and now cnt is: 7
I'm 4 th Go Routine! :D and now cnt is: 6
I'm 5 th Go Routine! :D and now cnt is: 5
I'm 6 th Go Routine! :D and now cnt is: 4
I'm 7 th Go Routine! :D and now cnt is: 3
I'm 8 th Go Routine! :D and now cnt is: 2
I'm 9 th Go Routine! :D and now cnt is: 1
I'm 10 th Go Routine! :D and now cnt is: 0
cnt is now:  0

1번부터 10번까지의 익명함수들이 차례대로 접근을 하고, cnt는 10부터 0까지 차례대로 떨어질 것이다.

 

하지만 Golang에서 고루틴을 사용한 결과,

고루틴의 접근 순서는 1 → 2 → 6 → 4 → 5 → 10 → 3 → 8 → 9 → 7 이었으며,

고루틴의 출력 순서는 3 → 5 → 1 → 2 → 6 → 4 → 8 → 9 → 7 10 이었다.

 

이는 고루틴이 접근 순서가 달라도, 병목(Deadlock) 현상이나 막힘(Block) 현상 발생시 같은 스레드 내에서 타 고루틴으로 분기하는 연산을 하는 것으로 설명될 수 있다.

(이에 대한 더 자세한 설명은 심화편에서 다뤄지고 있다.)

(해당 링크: 2020/01/12 - [IT/Go 언어 (Golang)] - [Golang] Go Routine (고 루틴) - Golang의 꽃 [심화])

 

[Golang] Go Routine (고 루틴) - Golang의 꽃 [심화]

이 론 어느 프로그래밍 언어나 해당 언어만의 강점, 혹은 "꽃"이라고 불릴 만한 것이 있다. 예를 들어 C언어의 꽃이라고 한다면 누가 물어도 "포인터"일 것이며, Python 같은 경우 "Life is too short, you need P..

underflow101.tistory.com


이러한 고루틴의 동시성을 이용하면,

이벤트 분산처리나 거대한 프로그램의 가속화를 이뤄볼 수 있다.

 

물론, 위에 나온대로 접근 순서와 실행 순서가 다를 수 있으므로 해당 순서가 중요하다면 sync.Wait() 함수 등으로 정확히 묶어 순서가 어긋나지 않도록 해야 한다.

그렇지 않으면 Fatal Error를 뿜어낼테니...

반응형