Concurrent Go의 교착 상태 이해: 고루틴 내 버퍼링되지 않은 채널
Go의 동시성 모델에서 채널은 고루틴 간 통신을 위한 중요한 도구입니다. 그러나 채널을 부적절하게 사용하면 다음 코드 조각에 표시된 대로 교착 상태가 발생할 수 있습니다.
package main import "fmt" func main() { c := make(chan int) c <- 1 fmt.Println(<-c) }
이 코드를 실행하면 다음 오류 메시지와 함께 교착 상태가 발생합니다.
fatal error: all goroutines are asleep - deadlock!
이 교착 상태는 왜 발생합니까?
문제는 다음을 사용하는 데 있습니다. 동일한 고루틴 내의 버퍼링되지 않은 채널. 버퍼링되지 않은 채널에는 내부 저장소가 없습니다. 즉, 다른 고루틴이 값을 읽을 때까지 버퍼링되지 않은 채널로 값을 보내는 것이 차단됩니다.
이 경우 goroutine은 채널 c에 값을 보내고 채널 c에서 값을 수신하려고 시도합니다. 같은 채널을 순차적으로 값을 받을 다른 고루틴이 없기 때문에 송신자 고루틴이 무한정 멈춰 교착상태가 발생합니다.
어떻게 고칠 수 있나요?
해결책은 두 가지입니다. :
c := make(chan int, 1)
이렇게 하면 버퍼 크기가 1인 채널이 생성되어 하나의 값을 차단하지 않고 저장할 수 있습니다.
package main import "fmt" func main() { c := make(chan int) go func() { c <- 1 }() fmt.Println(<-c) }
이 예에서 송신자 고루틴은 값을 채널 c에 비동기적으로 보냅니다. 그런 다음 기본 고루틴은 교착 상태가 발생하지 않고 채널에서 값을 받습니다.
버퍼링되지 않은 채널의 동작을 이해하고 부적절한 사용을 피하는 것은 효율적이고 차단되지 않는 동시 Go 프로그램을 작성하는 데 중요합니다.
위 내용은 동일한 고루틴의 버퍼링되지 않은 채널에서 전송 및 수신이 Go에서 교착 상태를 일으키는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!