티스토리 뷰
Go 컨텍스트
Context 타입은 여러 Go 루틴에서 동시에 안전하게 사용할 수 있는, 요청 범위 데이터에 접근하기 위한 안전한 방법을 구현한다.
Context 패키지의 주 목적은 Context타입을 정의하고 취소 기능을 지원하는 것이다.
하나의 문맥 으로 해석할 수 있는 context
는 http 1개의 요청이 들어와서 응답이 나갈때까지 한개의 문맥이나 맥락으로 볼 수 있듯 함수가 동작함에 있어서 문맥을 넣어서 진행 상황을 파악 할 수 있게 해준다.
특히 go루틴 같은경우 go루틴이 끝나는 시점이 필수적이기 때문에 context
를 넣어서 끝날 시점을 정해 줄 수도 있다.
개념적으로는 하나의 무전기라고 볼 수 있다.
일꾼 하나를 보내면서 context
라는 무전기 하나 들려 보내고, 그리고 만약 필요하다면 "시켰던 일 중지하고 퇴근해!" 라고 말할 수 있다.
주요 메서드
Background()
Background 메서드는 값이 없는 빈 Context를 반환한다. 일반적으로 main 함수에서 최상위 Context로 사용된다.
WithCancel(parent Context) (ctx Context, cancel CancelFunc)
context.WithCancel 함수로 생성한 컨텍스트에는 취소 신호를 보낼 수 있다.
WithDeadline(parent Context, d time.Time) (Context, CancelFunc)
WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
일정 시간이 되면 자동으로 컨텍스트에 취소 신호가 전달되도록 하려면 context.WithDeadline 함수나
context.WithTimeout 함수를 사용하여 컨텍스트를 생성하면 된다.
WithValue(parent Context, key, val interface{}) Context
한번 생성된 컨텍스트는 변경할 수 없다. 그래서 컨텍스트에 값을 추가하고 싶을 때는 context.WithValue 함수로 새로운 컨텍스트를 만들어 주어야 한다.
예제
context.WithCancel
context.WithCancel에 대한 예제입니다.
1초마다 hello world를 출력하는 프로그램인데 프로그램을 돌리던 중 5초뒤에 testFunction()에 문제가 생겨서 testFunction이 종료 되었습니다. 이때 안에서 동시에 실행된 testGoRoutine은 context가 없다면 testFunction이 종료되어도 계속 돌아가게 될 것 입니다.
testFunction이 종료될때 testGoRoutine또한 종료 시켜야 한다면 context를 넣어줘서 cancel을 통해 testGoRoutine을 종료 시킬 수 있습니다.
package main
import (
"context"
"fmt"
"time"
)
func testFunction() {
ctx, cancel := context.WithCancel(context.Background())
go testGoRoutine(ctx)
time.Sleep(5 * time.Second) // 5초 뒤 testFunction 종료
cancel() // ctx.Done()으로의 신호
}
func testGoRoutine(ctx context.Context) {
for {
select {
case <-ctx.Done():
return // 종료
default:
fmt.Println("hello world!")
time.Sleep(1 * time.Second)
}
}
}
func main() {
testFunction()
time.Sleep(10 * time.Second)
}
context.WithTimeout, context.WithDeadline
context.WithCancel과 다른점은 시간 제한을 추가했다는 것 입니다.
context.WithCancel은 cancel()을 실행 시켜줘야Done()으로 신호를 보냈지만 timeout과 deadline은 시간이 지나거나, 시간이 되면 Done()으로 신호를 보내게 됩니다.
timeout은 몇초의 시간제한을 둔다 라는 제한을 건다면
deadline은 어느 시각까지 (2020년 1월 1일 12시)의 시간 제한을 건다는것에 차이가 있습니다.
package main
import (
"context"
"fmt"
"time"
)
func contextWithTimeOut() {
ctx_background := context.Background()
ctx, _ := context.WithTimeout(ctx_background, 3*time.Second) //3초의 타임아웃
go testGoRoutine2(ctx)
time.Sleep(time.Second * 2)
}
func testGoRoutine2(ctx context.Context) {
for {
select {
case <-ctx.Done(): // 3초뒤 신호가 들어옴
return // 종료
default:
fmt.Println("hello world!")
time.Sleep(1 * time.Second)
}
}
}
func main() {
go contextWithTimeOut()
time.Sleep(10 * time.Second)
}
'LANGUAGE > go' 카테고리의 다른 글
[golang] 🚙 goroot, gopath, gomodule (0) | 2021.08.01 |
---|
- Total
- Today
- Yesterday
- django
- Python
- 팰린드롬수
- query
- leetcode
- 소프트웨어 장인
- 의대 신경학 강의
- 백준
- 방금그곡
- for-else
- taggit
- gunicorn
- Two Scoops of Django
- 프로그래머스
- go
- 독후감
- 문자열 뒤집기
- conTeXt
- stdout
- go context
- 파이썬
- dfs
- sql lite
- ManyToMany
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |