메뉴

문서정보

예제로 살펴보는 Go : Channel Synchronization

여러 개의 고루틴을 관리하다 보면, 이들을 동기화 해야 하는 필요가 생긴다. 여기에서는 고루틴이 끝날 때까지 기다리는 방법을 살펴본다.
package main

import (
    "fmt"
    "time"
)

func worker(done chan bool) {
    fmt.Println("working...")
    time.Sleep(time.Second * 1)
    fmt.Println("done")
    
    done <- true
}

func main() {
    done := make(chan bool, 1)
    go worker(done)
    <- done
}
		
worker는 매개변수로 채널을 받는다. 소모되는 작업시간은 sleep로 대신했다. 작업이 끝나면 채널에 작업이 끝냈음을 알리는 메시지를 전송한다.

main함수는 worker 고루틴을 실행하고 채널로 부터 메시지를 기다린다. 만약 <- done을 제거하면, 이 프로그램은 worker가 작업을 종료하기 전에 종료되 버릴 거다. 이 코드는 우아한 종료에 응용 할 수 있을 거다.

package main

import (
    "fmt"
    "time"
)

type job struct {
    Name string
    Result string 
}

func worker(j chan job) {
    for {
        myjob := <-j
        if myjob.Name == "close" {
            time.Sleep(time.Second * 1)
            myjob.Result = "종료"
        } else {
            fmt.Println("작업 수행: ", myjob.Name)
            myjob.Result = "완료"
        }
        j <- myjob 
    }
}

func main() {
    done := make(chan job, 1)
    go worker(done) 
    for _,i := range []string{"job 1", "job 2"} {
        done <- job{Name:i}
        result := <-done
        fmt.Println("Job: ", result.Name, result.Result)
    }
    done <- job{Name:"close"}
    result := <- done
    fmt.Println("결과: ", result)
}
		
위 코드는 우아한 종료의 예를 보여주고 있다. worker함수는 작업의 상세 내용을 담고 있는 job구조체 타입의 채널을 매개변수로 받는다. worker는 작업의 이름이 "close"일 경우에는 자원을 정리한다. main 함수는 작업이 종료되기를 기다렸다가 프로그램을 종료한다.

예제 코드 : Channel Directions