Go 채널 및 교착 상태: 차단 문제 이해
Go 채널 작업 시 적절한 동기화가 보장되지 않으면 교착 상태가 발생할 수 있습니다. 다음 예를 고려하십시오.
<code class="go">func main() { c1 := make(chan int) c2 := make(chan int) // Create two goroutines that ping-pong values between channels go func() { for i := range c1 { println("G1 got", i) c2 <- i } }() go func() { for i := range c2 { println("G2 got", i) c1 <- i } }() // Send an initial value to start the chain c1 <- 1 // Wait for a long time to observe the ping-ponging behavior time.Sleep(1000000000 * 50) }</code>
이 코드는 기본 함수가 종료될 때까지 값을 무기한으로 성공적으로 인쇄합니다. 그러나 채널 중 하나에 다른 값이 전송되면 교착 상태가 발생합니다.
<code class="go">func main() { c1 := make(chan int) c2 := make(chan int) // Create two goroutines to ping-pong values between channels go func() { for i := range c1 { println("G1 got", i) c2 <- i } }() go func() { for i := range c2 { println("G2 got", i) c1 <- i } }() // Send an initial value to start the chain c1 <- 1 // Wait for a short time time.Sleep(1000000000 * 1) // Send another value to the channel c1 <- 2 // Wait for a long time to observe the issue time.Sleep(1000000000 * 50) }</code>
이 경우 "2" 값을 전송한 후 출력이 중단됩니다.
G1 got 1 G2 got 1 G1 got 1 G2 got 1 G1 got 2
이 문제는 고루틴이 서로 해당 채널에서 값을 수신하기를 기다리고 있기 때문에 발생합니다. 따라서 두 고루틴 모두 진행할 수 없으며 교착 상태가 발생합니다.
교착 상태를 방지하려면 채널이 제대로 동기화되었는지 확인하세요. 한 가지 접근 방식은 다음 예와 같이 용량이 0이 아닌 버퍼링된 채널을 사용하는 것입니다.
<code class="go">// ... (Same code as before) c1 := make(chan int, 1) // Buffered channel with capacity of 1 c2 := make(chan int, 1)</code>
버퍼링된 채널을 사용하면 다른 고루틴이 아직 이전 값을 수신하지 않았더라도 하나의 고루틴이 값을 보낼 수 있습니다. 하나. 이는 설명된 것과 같은 상황에서 교착 상태를 방지하는 데 도움이 됩니다.
위 내용은 Go 채널이 교착 상태를 일으키는 이유는 무엇이며 이를 방지할 수 있는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!