Go에서는 채널에서 메시지가 수신되는 순서를 이해하는 것이 약간 까다로울 수 있습니다. . 제공하신 코드를 자세히 살펴보겠습니다.
func main() { messages := make(chan string) go func() { messages <- "hello" }() go func() { messages <- "ping" }() msg := <-messages msg2 := <-messages fmt.Println(msg) fmt.Println(msg2) }
다음 설명은 귀하의 우려 사항을 해결하고 현재 상황에 대한 더 명확한 이해를 제공합니다.
먼저 다음과 같은 차단 작업을 이해하는 것이 중요합니다. 버퍼링되지 않은 채널에서 전송하거나 수신하는 경우 순서가 보장되지 않습니다. Go에서는 고루틴 실행이 동시이며 기본적으로 고루틴 실행에 대해 정의된 순서가 없습니다.
첫 번째 고루틴이 채널에 "hello"를 보내려고 할 때 현재 대기 중인 수신자가 없으면 고루틴은 다음과 같습니다. 막힌. 마찬가지로, 두 번째 고루틴이 "ping"을 보내려고 시도하면 역시 차단됩니다.
이제 msg := <-messages 문에 도달하면 프로그램은 차단된 고루틴 중 하나를 임의로 차단 해제합니다. 차단되지 않은 고루틴에서 보낸 메시지는 msg로 수신됩니다.
msg2 := <-messages에서도 동일한 프로세스가 발생합니다. 또 다른 고루틴은 차단 해제되고 해당 고루틴에서 보낸 메시지는 msg2로 수신됩니다.
고루틴이 차단 해제되고 메시지를 메시지로 전송하는 순서는 결정적이지 않습니다. 이것이 루틴이 대안적으로 실행되어야 한다고 가정했음에도 불구하고 "hello" 앞에 "ping"이 지속적으로 인쇄되는 이유입니다.
이를 확인하려면 고루틴에 인쇄 문을 추가해 볼 수 있습니다.
func main() { messages := make(chan string) go func() { fmt.Println("Sending 'hello'") messages <- "hello" fmt.Println("Sent 'hello'") }() go func() { fmt.Println("Sending 'ping'") messages <- "ping" fmt.Println("Sent 'ping'") }() msg := <-messages msg2 := <-messages fmt.Println(msg) fmt.Println(msg2) }
코드를 여러 번 실행하면 고루틴의 인쇄 문의 순서가 달라질 수 있음을 알 수 있습니다. 이는 고루틴 실행의 비결정적 특성을 더욱 보여줍니다.
요약하자면, 버퍼링되지 않은 채널에서는 채널의 출력 순서가 보장되지 않으며 해당 고루틴이 차단 해제되는 순서에 따라 달라집니다.
위 내용은 Go의 버퍼링되지 않은 채널의 출력 순서가 비결정적인 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!