Go routines

8135 단어 gogo

⭐️ 고루틴

  • 함수를 동시에 실행시키는 기능
  • 다른 언어의 스레드 생성보다 간단하고, 운영체제의 리소스를 적게 사용한다.

⚡️ 함수를 호출할 때 앞에 go 키워드를 붙이면 고루틴으로 실행된다.
go function()

🔥 주의점

main 함수에 고루틴만 사용하게되면 main 함수와 동시에 실행되기 때문에 바로 종료되버린다.(main 함수는 고루틴을 기다려주지 않음)
ex)

package main

import (
	"fmt"
	"time"
)

func main() {
	go Count("a")
	go Count("b")
	time.Sleep(time.Second * 5)
}

func Count(person string) {
	for i := 0; i < 10; i++ {
		fmt.Println(person, "is ", i)
		time.Sleep(time.Second)
	}
}

원래라면 10초동안 함수 2개가 동시에 실행되지만 main 함수는 5초동안 살아있기 때문에 5초까지 세고 프로그램이 끝난다. -> 채널을 이용해 해결

⭐️ 채널

  • 고루틴끼리 데이터를 주고받고, 실행 흐름을 제어하는 기능
  • 값이 아닌 레퍼런스 타입(마치 파이프같은)
  • 고루틴이 채널에 값을 보내고 꺼냄

make를 이용해 공간을 할당한다.
c := make(chan int) -> int형 채널 생성

채널을 매개변수로 받는 함수는 반드시 go 키워드를 사용하여 고루틴으로 실행해야 한다.
go sum(1, 2, c)

매개변수로 받을 때는 변수명 chan 자료형 형식으로 사용된다.

func sum(a int, b int, c chan int) {
	c <- a+b
}

int형 채널을 매개변수로 받고 채널에 a+b 값을 보낸다.

채널에 값을 보낼때에는 채널 <- 값 형식으로 사용된다.(= 대신)
c <- 는 채널에 값을 보내고 값이 꺼내질 때까지 대기한다. 채널 값이 꺼내지면 다음 코드를 실행

그 후에 main 함수에서는 채널에서 값을 가져온다.
n := <- c

값을 받을 때는 값 <- 채널 형식으로 사용된다.(변수에 대입하지 않고도 <-c를 print하는 등 바로 사용 가능하다.)
<- c는 채널에서 값이 들어올 때까지 대기한다. 채널 값이 들어오면 값을 꺼내고 다음 코드를 실행

🔥 즉, 채널은 값을 주고받는 동시에 동기화 역할까지 수행한다.

main 함수에서 고루틴을 기다려주지 않는 문제를 채널을 이용해 해결

c <- 으로 채널에 값을 보내는 갯수보다 <- c으로 채널에서 값을 받는 갯수가 더 많다면 오류 발생(영원히 대기하는 경우 때문)
그 반대의 경우는 오류가 발생하진 않지만 채널에 값이 남아있는 채로 종료됨

📗 채널을 활용해 고루틴의 코드 실행 순서 제어(동기)

func main() {
	done := make(chan bool) // 동기 채널 생성
	count := 3

	go func() { // 익명 함수
		for i := 0; i < count; i++ {
			done <- true                // 고루틴에 true를 보냄, 값을 꺼낼 때까지 대기
			fmt.Println("고루틴 : ", i)    // 반복문의 변수 출력
			time.Sleep(time.Second * 1) // 1초 대기
		}
	}()

	for i := 0; i < count; i++ {
		<-done // 채널에 값이 들어올 때까지 대기, 값을 꺼냄
		fmt.Println("메인 함수 : ", i)
	}
}

익명 함수 부분
1. 먼저 고루틴을 생성하고 반복문을 실행할 때마다 채널 done에 true값을 보낸 뒤 1초를 기다린다.
2. 동기 채널이므로 done에 값을 보내면 다른 쪽에서 값을 꺼낼 때까지 대기한다.

메인 함수 부분
1. 메인 함수에서는 반복문을 실행할 때마다 채널 done에서 값을 꺼낸다.
2. <-done 부분에서 채널에 값이 들어올 때까지 대기한다.
3. 앞의 고루틴에서 done에 값을 보냈기 때문에 값을 꺼낸뒤 다음 코드를 진행한다.
4. 고루틴쪽 대기도 종료되면서 다시 반복문이 실행된 뒤 채널에 값을 보낸다.

❗️실행 순서 : 고루틴 -> 메인함수 -> 고루틴 -> 메인함수 ...

좋은 웹페이지 즐겨찾기