Goroutines 기초
Coddy GO 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 107개 중 59번째.
고루틴(goroutine)은 Go 런타임에 의해 관리되는 경량 실행 스레드입니다. 상당한 메모리를 소비하는 전통적인 스레드와 달리, 고루틴은 단 몇 킬로바이트의 스택 공간으로 시작하므로 수천 개를 동시에 실행할 수 있습니다.
고루틴(goroutine)을 시작하려면, 함수 호출 앞에 go 키워드를 배치하기만 하면 됩니다:
func sayHello(name string) {
fmt.Println("Hello,", name)
}
func main() {
go sayHello("Alice") // 동시에 실행됨
go sayHello("Bob") // 동시에 실행됨
time.Sleep(100 * time.Millisecond)
fmt.Println("Done")
}go sayHello("Alice")가 실행될 때, sayHello가 끝날 때까지 기다리지 않습니다. 대신, sayHello가 백그라운드에서 실행되는 동안 즉시 다음 줄로 넘어갑니다. 이것이 time.Sleep이 필요한 이유입니다. 이것이 없으면 고루틴이 완료되기 전에 main이 종료됩니다.
익명 함수를 사용하여 고루틴을 실행할 수도 있습니다:
go func(msg string) {
fmt.Println(msg)
}("Hello from goroutine")main 함수 자체는 고루틴(goroutine)에서 실행됩니다. 이 함수가 반환되면 다른 모든 고루틴은 즉시 종료되며, 작업을 마칠 기회를 얻지 못합니다. time.Sleep을 사용하는 것은 임시적인 해결책입니다. 향후 레슨에서는 채널(channels)과 웨이트 그룹(wait groups)을 사용한 적절한 동기화 기법을 배우게 됩니다.
챌린지
쉬움고루틴(goroutines)을 사용하여 여러 작업을 동시에 실행하는 태스크 러너(task runner)를 만들어 보겠습니다. 메인 프로그램이 계속 실행되는 동안 작업이 백그라운드에서 실행되는 간단한 시스템을 구축하여, 고루틴이 어떻게 동시 실행을 가능하게 하는지 실습해 봅니다.
코드는 다음 두 개의 파일로 구성합니다:
tasks.go: 작업 실행 로직을 정의합니다.Name(string)과Duration(int, 밀리초 단위) 필드를 가진Task구조체를 생성합니다.Task에Run()메서드를 구현합니다. 이 메서드는 작업의 기간(duration)만큼 대기(sleep)하여 작업을 시뮬레이션한 후,Task [Name] completed를 출력합니다.각 작업의
Run()메서드를 고루틴으로 실행하는RunAllTasks(tasks []Task)함수를 생성합니다. 모든 고루틴을 실행한 후, 작업들이 완료될 수 있도록 500밀리초 동안 대기한 다음All tasks launched를 출력해야 합니다.main.go: 작업 정보를 읽고 동시 실행을 조율합니다.작업의 개수를 읽은 다음, 각 작업의 이름과 기간을 읽습니다. 작업들을 생성하고
RunAllTasks에 전달합니다. 함수가 반환된 후,Main function done을 출력합니다.
다음과 같은 입력이 제공됩니다:
- 1행: 작업의 개수 (정수)
- 다음 행들: 각 작업당 두 줄 - 작업 이름, 그 다음 밀리초 단위의 기간
예를 들어, 다음과 같이 입력된 경우:
3
Download
100
Process
50
Upload
75출력에는 작업 완료 메시지(동시성으로 인해 순서는 다를 수 있음)와 그 뒤를 잇는 완료 메시지들이 표시되어야 합니다:
Task Process completed
Task Upload completed
Task Download completed
All tasks launched
Main function done참고: 고루틴은 동시에 실행되므로, 일반적으로 기간이 짧은 작업이 먼저 끝납니다. 작업 완료 순서는 기간에 따라 달라지며, 짧은 작업이 긴 작업보다 먼저 완료됩니다.
지연 시간을 위해 time.Sleep을 time.Duration 및 time.Millisecond와 함께 사용하세요. RunAllTasks에서 대기(sleep)하지 않으면 고루틴이 작업을 마치기 전에 함수가 반환된다는 점을 기억하세요.
치트 시트
고루틴(goroutine)은 Go 런타임에 의해 관리되는 경량 실행 스레드입니다. 고루틴은 단 몇 킬로바이트의 스택 공간으로 시작하므로, 수천 개의 고루틴을 동시에 실행할 수 있습니다.
고루틴을 시작하려면 함수 호출 앞에 go 키워드를 배치하세요:
func sayHello(name string) {
fmt.Println("Hello,", name)
}
func main() {
go sayHello("Alice") // 동시에 실행됨
go sayHello("Bob") // 동시에 실행됨
time.Sleep(100 * time.Millisecond)
fmt.Println("Done")
}go sayHello("Alice")가 실행될 때, sayHello가 끝날 때까지 기다리지 않습니다. 대신, sayHello가 백그라운드에서 실행되는 동안 즉시 다음 줄로 넘어갑니다.
익명 함수를 사용하여 고루틴을 실행할 수도 있습니다:
go func(msg string) {
fmt.Println(msg)
}("Hello from goroutine")main 함수 자체도 고루틴에서 실행됩니다. main 함수가 반환되면 다른 모든 고루틴은 즉시 종료됩니다. main 함수가 종료되기 전에 고루틴이 완료될 수 있도록 time.Sleep을 사용하세요.
직접 해보기
package main
import (
"fmt"
)
func main() {
// 작업의 개수를 읽습니다
var numTasks int
fmt.Scanln(&numTasks)
// TODO: 작업을 담을 슬라이스를 생성합니다
// TODO: 각 작업의 이름과 소요 시간을 읽습니다
// 각 작업에 대해:
// - 작업 이름을 읽습니다
// - 소요 시간을 읽습니다 (정수)
// - Task를 생성하고 슬라이스에 추가합니다
// TODO: 작업 슬라이스를 사용하여 RunAllTasks를 호출합니다
// TODO: "Main function done"을 출력합니다
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
8에러 처리와 OOP
error 인터페이스사용자 정의 에러 타입에러 래핑 (fmt.Errorf)센티넬 에러errors.Is()와 errors.As()Panic, Defer, Recover요약 - 파일 파서