>  기사  >  백엔드 개발  >  Go 동시성: 채널을 사용할 때 내 프로그램이 예기치 않은 출력을 인쇄하는 이유는 무엇입니까?

Go 동시성: 채널을 사용할 때 내 프로그램이 예기치 않은 출력을 인쇄하는 이유는 무엇입니까?

DDD
DDD원래의
2024-10-28 16:16:17905검색

Go Concurrency: Why Does My Program Print Unexpected Output When Using Channels?

Go 동시성 및 채널 혼란 해결

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"를 인쇄한 다음 종료하는 것입니다. . 그러나 실제 출력에는 sum 함수의 결과가 포함됩니다.

display first message: hello
10000000000

설명

라인의 주요 고루틴이 차단된다는 사실로 인해 혼란이 발생합니다.

<code class="go"><-c</code>

이는 기본 고루틴이 채널 c에서 값을 수신할 때까지 실행을 계속할 수 없음을 의미합니다. 디스플레이와 합계 모두 c에 참값을 전송하여 기본 고루틴을 차단 해제합니다. 그러나 스케줄러는 어떤 고루틴을 먼저 실행할지 선택할 수 있습니다.

가능한 실행 순서:

  1. 메인은 표시 및 합계를 위해 두 개의 고루틴을 생성합니다.
  2. 스케줄러는 표시를 실행합니다. 먼저 메시지를 인쇄하고 채널 전송을 차단합니다.
  3. 스케줄러는 sum 고루틴으로 전환합니다.
  4. Sum은 결과를 계산하고 인쇄합니다.
  5. 스케줄러는 표시를 다시 시작합니다. , 이는 채널에 값을 전송합니다.
  6. 메인 고루틴은 값을 수신하고 종료합니다.

해결책

프로그램은 첫 번째 결과만 인쇄하므로 결과 채널을 사용할 수 있습니다.

<code class="go">func display(msg string, result chan string) {
    result <- msg
}</code>

주 함수를 다음으로 변경합니다.

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

    go display("hello", result)
    fmt.Println(<-result)
}</code>

위 내용은 Go 동시성: 채널을 사용할 때 내 프로그램이 예기치 않은 출력을 인쇄하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.