>백엔드 개발 >Golang >Go 루틴 작업이 완료되기 전에 Go 프로그램이 종료됩니다.

Go 루틴 작업이 완료되기 전에 Go 프로그램이 종료됩니다.

PHPz
PHPz앞으로
2024-02-08 22:57:20902검색

Go 程序在 goroutine 工作完成之前退出

이 기사에서 PHP 편집자인 Xiaoxin은 Go 프로그램에 관한 중요한 문제, 즉 고루틴 작업이 완료되기 전에 종료하는 상황을 소개합니다. Go 언어에서 고루틴은 작업을 동시에 실행할 수 있는 경량 스레드입니다. 그러나 고루틴의 작업이 완료되기 전에 프로그램이 종료될 수 있는 경우, 프로그램이 작업을 올바르게 완료하는지 확인하기 위해 이 상황을 처리하는 방법을 이해해야 합니다. 다음 콘텐츠에서는 이 문제를 살펴보고 이를 해결하기 위한 몇 가지 솔루션을 제공합니다.

질문 내용

채널을 올바르게 차단하고 폐쇄하는 방법을 이해하는 데 어려움을 겪고 있습니다. 임의의 수의 작업자를 시작하고 있는데 작업자가 끝나기 전에 주요 기능이 종료되거나 닫히지 않은 채널로 인해 중단되는 것으로 나타났습니다. 작업자가 기본 채널을 종료하지 않고 채널을 읽는 것을 중지한 다음, 완료되면 채널을 정상적으로 닫아 루프를 종료하는 더 나은 방법이 필요합니다. 내가 시도하는 모든 시도는 교착 상태로 끝납니다.

대기 그룹 사용을 포함하여 몇 가지 방법을 시도했지만 문제가 지속됩니다. time.sleep를 추가하면 프로그램이 예상대로 작동하지만 주석을 달면 아무 작업도 수행되지 않는 것으로 나타났습니다.

으아악

다음은 sleep를 유지하는 실제 예제 https://go.dev/play/p/qhqnj-ajqbi입니다. 이것은 절전 시간 초과가 주석 처리된 손상된 코드입니다.

으아악

나도 defer wg.done() 移动到 worker() func를 넣어봤지만 같은 문제이고 잠을 자지 않으면 작동하지 않습니다.

으아악

내가 잘못된 패러다임을 선택한 걸까요, 아니면 잘못된 패러다임을 사용하고 있는 걸까요?

해결 방법

저는 원래 "코드가 작동하도록 하려면 코드를 약간 조정할 수 있나요? 아니면 다시 생각해야 하나요? "라고 물었습니다. 제가 찾은 대답은 예, 약간의 조정이 있다는 것입니다.

채널에 대한 흥미로운 기본 개념을 배워야 했습니다. 닫힌 채널에서 데이터를 읽을 수 있습니다. 즉, 채널을 비울 수 있습니다. 원래 예에서 언급했듯이 range 채널을 닫을 수 있는 좋은 장소를 찾을 수 없기 때문에 절대 종료되지 않으며, 다른 창의적인 방법으로 강제로 적용해도 프로그램이 잘못된 동작을 보입니다

  • 채널의 모든 콘텐츠를 처리하지 않고 종료되었습니다
  • 교착 상태 또는 폐쇄된 채널에서 전송

이는 "real" 코드의 미묘한 차이로 인해 채널 콘텐츠를 처리하는 데 걸리는 시간이 채널을 채우는 데 걸리는 시간보다 길고 모든 것이 동기화되지 않기 때문입니다.

발신자에게 채널을 닫는 명확한 실용적인 방법이 없기 때문에(채널 튜토리얼의 99%에서 권장됨) 여러 작업자가 채널을 읽고 있는데 작업자가 채널에 대해 알지 못하는 경우 고루틴을 통해 실제로는 마지막 값을 읽는 메인에서 이 작업을 수행하는 것이 허용됩니다.

솔루션

작업자를 자체 sync.waitgroup에 래핑하고 worker.wait()를 사용하여 프로그램이 종료되는 것을 sync.waitgroup 中,并使用 worker.wait()阻止程序退出,从而允许工作“完成” ”。当没有更多数据要发送时,我独立地 close()

방지

하여 작업이 "완료"되도록 했습니다. ". 더 이상 보낼 데이터가 없으면 채널을 독립적으로 close()합니다. 즉, 작성자가 자신의 대기 그룹을 사용하여 완료할 때까지 기다려 차단합니다. close는 범위 루프 사례에 대한 종료를 제공합니다. , 채널의 기본값이 반환되면, 즉 채널 끝에 도달하면 eof 유형이 반환되기 때문에 채널이 닫힐 때까지 교차 채널 차단이 종료됩니다. workers.wait()내 의견은 얼마나 많은 값이 병렬로 푸시될지 모른다면 Go는 버퍼링되지 않은 채널의 길이를 알 수 있는 방법이 없다는 것입니다. 왜냐하면 채널을 닫을 때까지

범위 내에 있기 때문입니다.

. 닫혀있으니 종료값이나 끝까지 남은 내용을 읽는다는 뜻이다. 완료될 때까지 차단됩니다.

해결된 작업의 예

https://www.php.cn/link/2bf0ccdbb4d3ebbcb990af74bd78c658

비공개 채널 읽기 예시

https://www.php.cn/link/d5397f1497b5cdaad7253fdc92db610b

🎜 🎜출력🎜 으아악

위 내용은 Go 루틴 작업이 완료되기 전에 Go 프로그램이 종료됩니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 stackoverflow.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제