2017-05-08 1 views
2

컨텍스트 변수가 범위를 벗어나 취소가 명시 적으로 호출되지 않으면 context.Done()이 차단 해제됩니까?컨텍스트 변수가 golang에서 범위를 벗어나면 Context.Done()이 차단을 해제합니까?

func DoStuff() { 
    ctx, _ := context.WithCancel(context.Background()) 
    go DoWork(ctx) 
    return 
} 

윌 ctx.Done() (DoStuff의 복귀 후 DoWork에서 해제) :

은 이제 나는 다음과 같은 코드가 있다고 가정 해 봅시다?

이 스레드는 https://groups.google.com/forum/#!topic/golang-nuts/BbvTlaQwhjw입니다. Context.Done()은 컨텍스트 변수가 범위를 벗어 났을 때 해당 context.Done()이 차단을 해제한다고 선언하지만 아무도이를 확인하지 못했습니다. 문서의 모든 것.

+0

당신이 생각하는 사람은 어떤 주장도하지 않고 자동으로 취소되는지 여부를 묻는 것입니다. –

답변

5

아니요, 컨텍스트가 범위를 벗어날 때 자동으로 취소되지 않습니다. 일반적으로 defer cancel() (콜백을 사용하여 ctx.WithCancel())을 호출하여 컨텍스트가 취소되었는지 확인합니다.

https://blog.golang.org/context은 컨텍스트를 올바르게 사용하는 방법에 대한 개요를 제공합니다 (위의 defer 패턴 포함). 또한 소스 코드 https://golang.org/src/context/context.go은 매우 읽기 쉽기 때문에 자동 취소 기능을 제공하는 마법은 없다는 것을 알 수 있습니다.

2

"차단 해제"는 가장 분명한 용어가 아닙니다. Done()struct{}을 수신하거나 컨텍스트가 "취소됨"일 때 닫히는 채널 (또는 nil)을 반환합니다. 그 chan이 정확히 무엇인지, 또는 그것이 전송 될 때, 그것은 개별 구현에 달려 있습니다. WithDeadline과 같이 고정 된 시간에 보내거나 닫을 수도 있고 WithCancel과 같이 수동으로 완료 할 수도 있습니다.

키가 있지만, 결코 "자동"또는 보장 될 수는 없습니다. WithCancel으로 컨텍스트를 만들고 Done() 채널에서 읽을 경우 Cancel() 메서드가 호출 될 때까지 해당 읽기는 을 무기한으로을 차단합니다. 그런 일이 발생하지 않는다면 낭비되는 골 루틴이 생기고 애플리케이션을 실행할 때마다 애플리케이션의 메모리가 증가합니다.

컨텍스트가 완전히 범위를 벗어나면 (실행중인 goroutine이 수신 대기 중이거나 상위 컨텍스트에 대한 참조가없는 경우) 가비지 수집되고 모든 것이 사라집니다.

EDIT : 소스를 읽은 후 WithCancel처럼 보이며 친구들이 취소를 알리기 위해 goroutines를 생성합니다. 따라서 이어야합니다. goroutine 유출을 피하려면 Cancel을 호출해야합니다.

관련 문제