> 백엔드 개발 > Golang > time.Sleep()은 실제로 Go Scheduler에서 고루틴을 차단하고 스레드 관리에 영향을 미치나요?

time.Sleep()은 실제로 Go Scheduler에서 고루틴을 차단하고 스레드 관리에 영향을 미치나요?

Mary-Kate Olsen
풀어 주다: 2024-11-20 00:22:03
원래의
1032명이 탐색했습니다.

Does time.Sleep() Truly Block Goroutines and Impact Thread Management in the Go Scheduler?

time.Sleep()을 사용한 고루틴 및 스레드 관리

Go에서 고루틴은 런타임 스케줄러에 의해 관리되는 경량 스레드입니다. 고루틴 실행을 제어하기 위해 일반적으로 사용되는 함수 중 하나는 지정된 기간 동안 현재 고루틴의 실행을 차단하는 time.Sleep()입니다. 그러나 이는 time.Sleep()이 실제로 고루틴을 차단하고 Go 스케줄러의 스레드 관리에 영향을 미치는지에 대한 의문을 제기합니다.

고루틴 차단 이해

예, 시간입니다. Sleep()은 고루틴을 차단합니다. 호출되면 지정된 기간 동안 현재 고루틴의 실행을 일시 중지합니다. 이 시간 동안 고루틴은 어떤 작업도 수행하거나 이벤트에 응답할 수 없습니다.

스레드 생성 및 time.Sleep()

Go 프로세스에서 생성된 스레드 수 사용 가능한 CPU 코어, GOMAXPROCS 설정 및 작업 부하를 포함한 다양한 요소의 영향을 받습니다. time.Sleep()을 사용한다고 해서 반드시 새 스레드가 생성되는 것은 아닙니다.

Go 런타임 스케줄러는 "MPG 모델"(다중 프로세스, 다중 고루틴)을 활용하여 고루틴과 스레드를 관리합니다. 이 모델에서 M(다중) 고루틴은 P(다중) 스레드를 공유합니다. 고루틴이 차단되면 관련 P 스레드가 해제되어 다른 고루틴을 서비스할 수 있습니다.

예제 코드 분석

제공된 예제 코드를 살펴보겠습니다.

import (
    "runtime"
    "time"
)

func main() {
    runtime.GOMAXPROCS(4)
    ch := make(chan int)
    n := 1
    for i := 0; i < n; i++ {
        go func() {
            time.Sleep(60 * time.Second)
            ch <- 1
        }()
    }
    for i := 0; i < n; i++ {
        <-ch
    }
}
로그인 후 복사

이 예에서는:

  • GOMAXPROCS를 4로 설정하여 활성 스레드 수를 4로 제한합니다.
  • n개의 고루틴을 생성합니다. 여기서 각 고루틴은 60 동안 휴면합니다. 초 후 채널에 값을 보냅니다.
  • 채널에서 값을 받아 각 고루틴이 완료될 때까지 기다립니다.

n이 1일 때, 우리는 5개의 스레드를 관찰합니다. 실행 중인 각 고루틴에 대해 최소한 하나의 스레드가 있는지 확인합니다. n이 증가함에 따라 스케줄러가 차단된 여러 고루틴을 서비스하기 위해 P 스레드를 효율적으로 관리하기 때문에 스레드 수가 상대적으로 낮게 유지됩니다.

명시적 IO와의 차이점

두 번째 예에서 제공:

import (
    "fmt"
    "io/ioutil"
    "os"
    "runtime"
    "strconv"
)

func main() {
    runtime.GOMAXPROCS(2)
    data := make([]byte, 128*1024*1024)
    for i := 0; i < 200; i++ {
        go func(n int) {
            for {
                err := ioutil.WriteFile("testxxx"+strconv.Itoa(n), []byte(data), os.ModePerm)
                if err != nil {
                    fmt.Println(err)
                    break
                }
            }
        }(i)
    }
    select {}
}
로그인 후 복사

우리는 지속적으로 파일에 쓰는 200개의 고루틴을 만듭니다. 이 경우 고루틴이 time.Sleep()으로 명시적으로 차단되지 않더라도 IO 작업으로 인해 고루틴이 중단되어 더 많은 스레드(이 예에서는 202)가 생성됩니다. 이는 스레드 생성에 대한 비차단 작업의 영향을 강조합니다.

결론

Go 런타임 스케줄러는 스레드 생성 및 고루틴 실행을 효과적으로 관리합니다. time.Sleep()은 고루틴을 차단하지만 생성된 스레드 수는 동적이며 작업 부하의 영향을 받습니다. 스레드 사용을 제어하기 위해 명시적인 단계를 수행해야 하는 극단적인 상황이 발생하지 않는 한 개발자는 스레드 관리에 대해 걱정해서는 안 됩니다. 대부분의 경우 스케줄러는 이러한 측면을 자동으로 처리합니다.

위 내용은 time.Sleep()은 실제로 Go Scheduler에서 고루틴을 차단하고 스레드 관리에 영향을 미치나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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