Go의 교착 상태: "모든 고루틴이 절전 모드로 설정됨"
고루틴을 사용하여 작업할 때 교착 상태를 피하기 위해 채널 작업을 효과적으로 관리하는 것이 중요합니다. 이는 모든 고루틴이 무기한 차단되어 교착 상태가 발생할 때 발생합니다.
코드 이해
제공된 코드를 살펴보겠습니다.
package main import ( "fmt" "sync" "time" ) type Item struct { name string } type Truck struct { Cargo []Item name string } func UnloadTrucks(c chan Truck) { for t := range c { fmt.Printf("%s has %d items in cargo: %s\n", t.name, len(t.Cargo), t.Cargo[0].name) } } func main() { trucks := make([]Truck, 2) ch := make(chan Truck) for i, _ := range trucks { trucks[i].name = fmt.Sprintf("Truck %d", i+1) fmt.Printf("Building %s\n", trucks[i].name) } for t := range trucks { go func(tr Truck) { itm := Item{} itm.name = "Groceries" fmt.Printf("Loading %s\n", tr.name) tr.Cargo = append(tr.Cargo, itm) ch <- tr }(trucks[t]) } time.Sleep(50 * time.Millisecond) fmt.Println("Unloading Trucks") UnloadTrucks(ch) fmt.Println("Done") }
이 코드는 Truck 유형의 채널 ch를 생성하고 트럭에 식료품을 싣고 보내는 것을 시뮬레이션하기 위해 두 개의 고루틴을 실행합니다. 채널에. 그런 다음 UnloadTrucks를 호출하여 트럭의 내용을 검색하고 인쇄합니다.
교착 상태의 원인
문제는 채널 채널을 닫는 메커니즘이 없다는 것입니다. 모든 고루틴이 트럭을 채널로 보냈을 때 UnloadTrucks에서 루프를 종료하라는 신호가 없습니다. 이는 ch가 결코 도착하지 않는 값을 계속 수신하여 교착 상태가 발생한다는 것을 의미합니다.
해결 방법
교착 상태를 해결하려면 다음과 같은 경우 ch 채널을 명시적으로 닫아야 합니다. 로딩 고루틴이 완료되었습니다. sync.WaitGroup을 사용하여 실행 중인 고루틴 수를 계산하고 모두 완료되면 채널을 닫을 수 있습니다.
var wg sync.WaitGroup go func() { wg.Wait() close(ch) }() UnloadTrucks(ch)
이 수정을 통해 모든 고루틴이 트럭 로드를 완료하면 UnloadTrucks가 종료됩니다. Wait 함수는 WaitGroup 카운터가 0에 도달할 때까지 차단되어 모든 고루틴이 작업을 완료했음을 나타냅니다. UnloadTrucks에 채널을 닫으면 더 이상 수신할 트럭이 없다는 신호를 보내 루프를 정상적으로 종료할 수 있습니다.
위 내용은 모든 고루틴이 잠들어 있을 때 Go에서 교착 상태를 해결하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!