>백엔드 개발 >Golang >Infinite Go 루틴이 다른 고루틴이 채널로 전송하는 것을 차단하는 이유는 무엇입니까?

Infinite Go 루틴이 다른 고루틴이 채널로 전송하는 것을 차단하는 이유는 무엇입니까?

Linda Hamilton
Linda Hamilton원래의
2024-12-04 16:52:11556검색

Why Does an Infinite Go Routine Block Other Goroutines from Sending to Channels?

Go 루틴 차단 기타: 더 깊은 설명

Go에서 다음 코드는 무한 루프가 있는 고루틴처럼 보이는 비정상적인 동작을 보여줍니다. 다른 고루틴의 메시지가 의도한 채널에 도달하는 것을 방지합니다:

func main() {
   timeout := make(chan int)
   go func() {
      time.Sleep(time.Second)
      timeout <- 1
    }()

    res := make(chan int)
    go func() {
        for {
        }
        res <- 1
    }()
    select {
        case <-timeout:
            fmt.Println("timeout")
        case <-res:
            fmt.Println("res")
    }
}

대신 1초 후에 종료되면 프로그램은 무한 루프에 들어갑니다. 왜 이런 일이 발생합니까?

Go의 협력 스케줄링 이해

답은 Go가 고루틴에 협력 스케줄링을 사용하는 데 있습니다. 고루틴은 다음을 포함한 특정 조건에서 스케줄러에 제어권을 양보합니다.

  • 버퍼링되지 않은 채널 전송/수신 작업
  • 시스템 호출(예: 파일/네트워크 I/O)
  • 메모리 할당
  • time.Sleep() 호출
  • runtime.Gosched() 호출

첫 번째 고루틴의 무한 루프는 결코 양보하지 않으므로 다른 고루틴이 실행되고 채널에 메시지를 보내는 것을 방지합니다. 여기에는 결코 도착하지 않는 메시지를 기다리는 타임아웃 채널이 포함됩니다.

잠재적 솔루션

협조적인 일정으로 인해 이러한 상황이 발생할 수 있지만 잠재적인 솔루션이 있습니다. :

  • GOMAXPROCS 증가: 이 환경 변수는 여러 스레드를 사용하여 고루틴을 동시에 실행하여 하나의 고루틴이 다른 고루틴을 차단할 가능성을 줄입니다.
  • 선점형 스케줄러 사용(향후 목표): Go 언어 개발자는 강제로 전환하는 선점형 스케줄러 구현을 목표로 합니다. 고루틴 사이에서 차단 문제를 제거합니다.
  • 수동 항복: Runtime.Gosched() 함수를 사용하면 고루틴이 수동으로 스케줄러에 제어권을 양보하여 다른 것을 차단할 수 있는 무한 루프를 벗어날 수 있습니다.

위 내용은 Infinite Go 루틴이 다른 고루틴이 채널로 전송하는 것을 차단하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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