조건부 전송 및 수신을 위한 양방향 채널 선택
Go에서는 전송 및 수신 모두에 대해 버퍼링된 채널을 설정할 수 있습니다. 가용성에 따라 선택적 작업을 수행합니다. 다음 시나리오를 고려해보세요.
<code class="go">s := make(chan<- int, 5) r := make(<-chan int)
버퍼링된 송신 채널 s와 버퍼링되지 않은 수신 채널 r이 있습니다. 질문이 생깁니다: r에 데이터가 있는지 또는 s가 가득 차지 않았는지 확인하기 위해 두 채널을 모두 선택할 수 있습니까? 이는 다음의 기능을 모방하지만 CPU를 100% 소비하지 않습니다.
<code class="go">for { if len(s) < cap(s) { // Send something } if len(r) > 0 { // Receive something } }</code>
Default Case로 Select 구현
이를 달성하기 위해 다음을 활용할 수 있습니다. 기본 케이스가 있는 select 문. 기본적으로 두 채널 모두 준비되지 않은 경우 불필요한 리소스 소비를 피하기 위해 일시적으로 goroutine을 "휴면"합니다.
<code class="go">s := make(chan<- int, 5) r := make(<-chan int) for { v := valueToSend() // Value to be sent, evaluated upon each attempt select { case s <- v: fmt.Println("Sent value:", v) case vr := <-r: fmt.Println("Received:", vr) default: // Neither channel is ready, pause briefly time.Sleep(time.Millisecond * 1) } }
길이 및 용량 확인이 이상적이지 않은 이유
보내거나 받기 전에 채널의 길이나 용량을 확인하지 않는 것이 중요합니다. 확인하는 시점과 실제 작업 사이에 채널 상태가 변경되어 예기치 않은 차단이 발생할 수 있기 때문입니다. 예를 들면 다음과 같습니다.
<code class="go">if len(r) > 0 { // r is ready to receive // Other code... r <- // This may block if another goroutine has already received from r! }</code>
위 내용은 Go에서 차단하지 않고 채널 전송 및 수신을 모두 선택할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!