2016-08-25 6 views
-1

장기 실행 프로세스의 컨텍스트에서 생성 된 goroutine이 올바르게 "닫혀 있는지"확인하는 방법에 대한 근본적인 이해 문제가 있습니다. 나는 그 주제에 관한 대화를 보았고 모범 사례에 대해 읽었다. 내 질문을 이해하려면 비디오 "Advanced Go 동시성 패턴"을 참조하십시오. heregoroutine 정리, 최 적합 보장

컴퓨터에서 코드를 실행하는 경우 환경 변수 GOTRACEBACK=all을 내 보내면 패닉 발생 후 일상적인 상태를 볼 수 있습니다.

나는 여기에 원래 예를 들어 코드를 넣어 : naive이 (가 이동 놀이터에서 실행되지 않습니다, 나는 한 번 문을 사용 bacause 코드를 복사하고 로컬로 실행하십시오 같아요.)

의 결과를 실행 후 원래 구현의 공포는 오랫동안 실행중인 프로세스 특히 나쁜 시스템에 매달려 goroutines을 떠날의 근본적인 문제를 보여줍니다

panic: show me the stacks goroutine 1 [running]: panic(0x48a680, 0xc4201d8480) /usr/lib/go/src/runtime/panic.go:500 +0x1a1 main.main() /home/flx/workspace/go/go-rps/playground/ball-naive.go:18 +0x16b goroutine 5 [chan receive]: main.player(0x4a4ec4, 0x2, 0xc42006a060) /home/flx/workspace/go/go-rps/playground/ball-naive.go:23 +0x61 created by main.main /home/flx/workspace/go/go-rps/playground/ball-naive.go:13 +0x76 goroutine 6 [chan receive]: main.player(0x4a4ec6, 0x2, 0xc42006a060) /home/flx/workspace/go/go-rps/playground/ball-naive.go:23 +0x61 created by main.main /home/flx/workspace/go/go-rps/playground/ball-naive.go:14 +0xad exit status 2

입니다.

generator pattern with quit channel

(놀이터에서 다시 실행되지 않음, 원인 "프로세스가 너무 오래 걸립니다

for-select with default :

그래서 내 개인적인 이해를 위해 내가 여기에서 찾을 수 두 약간 더 복잡한 변형을 시도 ")

첫 번째 솔루션은 goroutine 실행 속도에 따라 실행 된 단계에서 비 결정 성을 유발하는 등 다양한 이유로 적합하지 않습니다.

이제 저는 생각했습니다. 그리고 여기에 마침내 질문이옵니다! - 끝내기 전에 시스템에서 모든 실행 추적을 제거하기 위해 종료 채널이있는 두 번째 솔루션이 적합 할 것입니다. 여하튼, "때로는"프로그램이 너무 빨리 종료되고 공황 상태가 시스템에 여전히 존재하는 추가 goroutine 실행 파일을보고합니다. 패닉 출력 :

panic: show me the stacks goroutine 1 [running]: panic(0x48d8e0, 0xc4201e27c0) /usr/lib/go/src/runtime/panic.go:500 +0x1a1 main.main() /home/flx/workspace/go/go-rps/playground/ball-perfect.go:20 +0x1a9 goroutine 20 [runnable]: main.player.func1(0xc420070060, 0x4a8986, 0x2, 0xc420070120) /home/flx/workspace/go/go-rps/playground/ball-perfect.go:27 +0x211 created by main.player /home/flx/workspace/go/go-rps/playground/ball-perfect.go:36 +0x7f exit status 2

내 질문은 : 바로 일이 안되는? 나는 패닉 상태로 앞으로 나아 가기 전에 정화 채널에 종료 채널을 사용합니다. artificial wait time for runnables to close

이 어쨌든, 그 해결책은 느낌이 좋지 않습니다뿐만 아니라보다 Runnable 많은 양의에 적용되지 않을 수 있습니다

는 여기 안전한 정리 동작을 구현하는 마지막 시도를 했습니까?

올바른 정리를 위해 권장되고 가장 관용적 인 패턴은 무엇입니까? 귀하가 출력에 속지하는 시간

+0

나는이 예제가 "프로그램 실행이 끝난 후 시스템에 매달린 goroutine"을 보여주는 방법을 이해하지 못한다. " Goroutines는 Go 런타임 개념으로, 프로그램 실행이 끝나면 종료됩니다. 해체가 여전히 발생하는 동안보고있는 내용이 출력됩니다. 이것들이 정리되기 전에 런타임에서 일어난 일을보고하지 못했습니다. 아니면 내가하는 말을 완전히 벗어요? –

+0

naive 예제의 루틴은 공유 채널에서 블로킹을 기다리고 있기 때문에 종료 할 수 없습니다. 비디오의 중요한 비트는 분 ~ 4.40 분 ~ 5.10 분입니다. 프로그램 자체가 종료되지만 아직 매달려있는 루틴이 남아 있습니다. – flx

+0

맞아요, 사과드립니다 - 장기간 진행되는 프로세스의 맥락에서 말하면서 실행중인 프로세스를 실제로 종료하는 것이 아니라는 것을 알았습니다. –

답변

0

에 대한

감사합니다 : 귀하의 "채널 종료와 발전기 패턴은"두 goroutines 실제로 가 제대로를 종료됩니다, 완벽하게 잘 작동합니다.

당신이 너무 일찍 공황 상태에 빠지기 때문에 트레이스에서 볼 수 있습니다. 주의 사항 : goroutine은 main과 동시에 실행해야합니다. main은 quit 채널에 신호를 보내 이러한 goroutine을 "중지"합니다.18 번과 19 번에이 두 가지를 보내면 32 번 라인에있는 두 번의 수신이 일어났습니다. 그리고 아무것도 더! 메인은 19 번과 20 번 라인 사이에 있으며, 플레이어의 goroutine은 32 번과 33 번 라인 사이에 있습니다. 메인에서의 패닉이 플레이어의 리턴 전에 발생하면 플레이어의 goroutine은 여전히 ​​거기에 있고 공포에 나옵니다 stacktrace. 이 goroutine은 스케줄러 만이 33 행의 리턴을 실행할 시간이 있다면 몇 밀리 세컨드 후에 끝났을 것입니다 (당신이 당황해서 죽이지는 않았을 것입니다).

이것은 한 달에 한 번씩 "동시 병음이 효과가 있다는 것을 알기위한 주된 목적"문제의 인스턴스입니다. 콩코렌트 goroutines가 작동하는 것을 볼 수는 있지만, 은 모두이 아닙니다. 두려움이 생기기 전에 2 밀리 초 동안 자려고하면 플레이어의 goroutines가 돌아가서 모든 것을 처리 할 시간이 있습니다.