왜 내 Go 코드는 \'첫 번째 메시지 표시: hello\' 대신 100억 개의 숫자 합계를 인쇄합니까?

DDD
풀어 주다: 2024-10-28 07:49:02
원래의
145명이 탐색했습니다.

Why does my Go code print the sum of 10 billion numbers instead of just

Go 동시성과 채널 혼란

문제

사용자가 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억 개의 숫자의 합도 포함됩니다.

답변

코드의 주요 문제는 스케줄러가 두 고루틴 중에서 자유롭게 선택할 수 있다는 것입니다. (표시 및 합계)이 차단되지 않습니다. 프로그래머는 디스플레이가 먼저 끝나고 합계가 완료되기 전에 채널에 데이터를 보낼 것으로 기대하지만 스케줄러의 비결정적 특성으로 인해 이러한 일이 발생하지 않을 수도 있습니다.

한 가지 가능한 실행 시나리오:

  1. main은 표시 및 합계를 위한 두 개의 고루틴을 생성합니다.
  2. 스케줄러는 즉시 표시로 전환됩니다.
  3. display는 메시지를 인쇄하고 수신자가 채널로 전송된 데이터를 수락할 때까지 기다리는 것을 차단합니다. .
  4. 스케줄러는 표시를 다시 시작하는 대신 합계를 실행합니다.
  5. sum은 100억 개의 숫자의 합계를 계산하고 인쇄합니다.
  6. 스케줄러는 합계가 완료된 후 표시를 다시 시작하도록 선택합니다.
  7. 디스플레이가 채널에 데이터를 보냅니다.
  8. 스케줄러는 채널에서 데이터를 받기 위해 메인으로 전환합니다.
  9. main은 합계를 인쇄하고 프로그램을 종료합니다.

이 문제를 해결하고 "첫 번째 메시지 표시: hello" 메시지가 독점적으로 인쇄되도록 하기 위한 한 가지 접근 방식은 결과 채널을 사용하여 디스플레이에서 메시지를 수신하고 프로그램을 즉시 종료하는 것입니다. 수정된 주요 기능은 다음과 같습니다:

<code class="go">func main() {
    result := make(chan string)

    go display("hello", result)
    fmt.Println(<-result)
}</code>
로그인 후 복사

위 내용은 왜 내 Go 코드는 \'첫 번째 메시지 표시: hello\' 대신 100억 개의 숫자 합계를 인쇄합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!