Go의 동시성 - 고루틴 사용

고루틴



goroutine은 동시성을 달성하는 데 도움이 되는 go의 기본 제공 프리미티브입니다. 함수 호출 전에 go 키워드를 추가하여 고루틴을 만들 수 있습니다. 이 키워드는 go 런타임에 새로운 자식 프로세스(일명 고루틴)를 생성하고 새 메모리 공간에서 해당 함수의 실행을 완료하도록 지시합니다.

포크 조인 모델



Go는 새 고루틴이 기본 고루틴에서 분기(생성)되고 기본 고루틴이 자식 고루틴을 생성한 후에도 작업을 계속하는 분기 조인 동시성 모델을 따릅니다. 고루틴이 메인 고루틴에서 분기된 후 몇 가지 작업을 수행하고 메인 고루틴에 다시 합류하며 고루틴이 메인 고루틴과 결합되는 지점을 조인 포인트라고 합니다. 조인 포인트 구현의 책임은 개발자에게 있습니다. 간단한 예를 통해 이를 실제로 살펴보겠습니다.

package main

import "fmt"

func sayHi(name string) {
    fmt.Printf("Hi %s\n", name)
}

func main() {
    fmt.Println("Program Started")

    go sayHi("Luffy")
    go sayHi("Zoro")
    go sayHi("Sanji")

    fmt.Println("Program Ended")
}


산출

Program Started
Program Ended


잠시만요, 함수 호출 전에 go 키워드를 사용하면 새 메모리 공간에서 해당 함수가 실행되지만 프로그램이 예상대로 작동하지 않는다고 전에 말씀드렸습니다. 왜 그래?

이 프로그램이 예상대로 작동하지 않는 이유는 새로운 고루틴을 생성할 때 해당 고루틴이 할당된 작업을 수행하지만 해당 작업이 수행되는 동안 메인 고루틴 AKA main 함수가 계속해서 작업을 수행하기 때문입니다. 메인 고루틴은 작업을 완료하고 프로그램이 종료됩니다. go 런타임은 자식 고루틴이 작업을 완료하는지 여부를 신경 쓰지 않습니다. 개발자는 자식 고루틴이 작업을 완료할 때까지 메인 고루틴을 기다리게 한 다음 종료합니다. 프로그램. 그래서, 우리는 그것을 어떻게 합니까?.

아래 다이어그램을 보면 위의 프로그램에서 무슨 일이 일어났는지 알 수 있습니다.



자식 고루틴이 작업을 완료하고 프로그램을 종료할 때까지 메인 고루틴을 기다리게 하는 방법에는 여러 가지가 있습니다. 가장 간단한 방법은 자식 고루틴이 작업을 완료하는 동안 메인 고루틴 종료를 지연시키는 일정 시간 동안 프로그램을 절전 모드로 만드는 것입니다. 이전 예제를 수정하여 실제로 작동하는 것을 봅시다.

package main

import (
    "fmt"
    "time"
)

func sayHi(name string) {
    fmt.Printf("Hi %s\n", name)
}

func main() {
    fmt.Println("Program Started")

    go sayHi("Luffy")
    go sayHi("Zoro")
    go sayHi("Sanji")

    //sleeps the program for 3 seconds.
    time.Sleep(3 * time.Second)

    fmt.Println("Program Ended")
}



Program Started
Hi Sanji
Hi Luffy
Hi Zoro
Program Ended


여기 위의 예에서 우리는 time.Sleep(3 * time.Second)를 사용하여 프로그램을 3초 동안 휴면 상태로 만들고, 메인 고루틴은 3초 동안 휴면 상태로 만듭니다. 자식 고루틴은 이제 작업을 완료할 시간이 있습니다. 메인 고루틴이 3초 후에 다시 시작되면 프로그램이 종료됩니다. time.Sleep()을 사용하는 것은 차단 호출을 만드는 가장 좋은 방법이 아니며 빌드 중인 심각한 프로젝트에서 이 작업을 수행해서는 안 됩니다. 대신 우리가 살펴볼 go의 동기화 표준 라이브러리에서 WaitGroup으로 알려진 것을 사용해야 합니다. 다른 시간에.

아래 이미지를 보면 이 프로그램에서 무슨 일이 일어났는지 알 수 있습니다.



위 프로그램의 출력을 보면 우리를 맞이하는 순서가 임의적입니다. 이 동작은 고루틴이 작업을 완료하기 전에 다른 고루틴이 있는지 여부를 신경 쓰지 않기 때문에 발생합니다. 작업을 수행하고 사라지는 것입니다. . 그러나 실제 문제에서는 작업이 수행되는 순서가 매우 중요하므로 goroutine 간의 통신을 처리하는 channels라는 것을 달성하기 위해 다른 기사에서 이에 대해 논의할 것입니다.

결론



고루틴은 go 프로그래밍 언어의 필수 부분이며 고루틴은 위에서 설명한 것처럼 매우 간단한 방법으로 동시성을 달성하는 데 도움이 됩니다. 그러나 여기에 go 키워드를 던지면 자신을 혼란에 빠뜨리는 정말 좋은 방법이 있습니다. 코드를 버그와 경합 상태로 가득 채울 수 있으므로 매우 합리적인 상황에서 사용하십시오.

행복한 코딩!

좋은 웹페이지 즐겨찾기