왜 내 Go 코드는 \'첫 번째 메시지 표시: hello\' 대신 100억 개의 숫자 합계를 인쇄합니까?
Oct 28, 2024 am 07:49 AMGo 동시성과 채널 혼란
문제
사용자가 Go 동시성을 이해하려고 합니다. 다음 코드 조각을 사용하는 채널:
<code class="go">package main import "fmt" func display(msg string, c chan bool) { fmt.Println("display first message:", msg) c <- true } func sum(c chan bool) { sum := 0 for i := 0; i < 10000000000; i++ { sum++ } fmt.Println(sum) c <- true } func main() { c := make(chan bool) go display("hello", c) go sum(c) <-c }</code>
주 함수가 채널에서 데이터를 수신하면 종료되어야 하기 때문에 예상되는 출력은 "첫 번째 메시지 표시: hello"뿐입니다. 그러나 실제 출력에는 100억 개의 숫자의 합도 포함됩니다.
답변
코드의 주요 문제는 스케줄러가 두 고루틴 중에서 자유롭게 선택할 수 있다는 것입니다. (표시 및 합계)이 차단되지 않습니다. 프로그래머는 디스플레이가 먼저 끝나고 합계가 완료되기 전에 채널에 데이터를 보낼 것으로 기대하지만 스케줄러의 비결정적 특성으로 인해 이러한 일이 발생하지 않을 수도 있습니다.
한 가지 가능한 실행 시나리오:
- main은 표시 및 합계를 위한 두 개의 고루틴을 생성합니다.
- 스케줄러는 즉시 표시로 전환됩니다.
- display는 메시지를 인쇄하고 수신자가 채널로 전송된 데이터를 수락할 때까지 기다리는 것을 차단합니다. .
- 스케줄러는 표시를 다시 시작하는 대신 합계를 실행합니다.
- sum은 100억 개의 숫자의 합계를 계산하고 인쇄합니다.
- 스케줄러는 합계가 완료된 후 표시를 다시 시작하도록 선택합니다.
- 디스플레이가 채널에 데이터를 보냅니다.
- 스케줄러는 채널에서 데이터를 받기 위해 메인으로 전환합니다.
- main은 합계를 인쇄하고 프로그램을 종료합니다.
이 문제를 해결하고 "첫 번째 메시지 표시: hello" 메시지가 독점적으로 인쇄되도록 하기 위한 한 가지 접근 방식은 결과 채널을 사용하여 디스플레이에서 메시지를 수신하고 프로그램을 즉시 종료하는 것입니다. 수정된 주요 기능은 다음과 같습니다:
<code class="go">func main() { result := make(chan string) go display("hello", result) fmt.Println(<-result) }</code>
위 내용은 왜 내 Go 코드는 \'첫 번째 메시지 표시: hello\' 대신 100억 개의 숫자 합계를 인쇄합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

인기 기사

인기 기사

뜨거운 기사 태그

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Go Language Pack 가져 오기 : 밑줄과 밑줄이없는 밑줄의 차이점은 무엇입니까?

이동 중에 테스트를 위해 모의 개체와 스터브를 작성하려면 어떻게합니까?

Beego 프레임 워크에서 페이지간에 단기 정보 전송을 구현하는 방법은 무엇입니까?

추적 도구를 사용하여 GO 응용 프로그램의 실행 흐름을 이해하려면 어떻게해야합니까?

GO에서 제네릭에 대한 사용자 정의 유형 제약 조건을 어떻게 정의 할 수 있습니까?

MySQL 쿼리 결과 목록을 GO 언어로 사용자 정의 구조 슬라이스로 변환하는 방법은 무엇입니까?

Linters 및 정적 분석 도구를 사용하여 GO 코드의 품질과 유지 관리를 향상시킬 수 있습니까?
