English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Go 언어에서 select 문은switch 문하지만 select 문에서 case 문은 통신을 참조합니다. 즉, 채널에서의 보내거나 받기 작업입니다.
문법:
select{ case SendOrReceive1: // 문장 case SendOrReceive2: // 문장 case SendOrReceive3: // 문장 ...... default: // 문장 }
이 문서에서는 default 상황을 사용하여 dead lock을 피하는 방법을 배울 것입니다. 하지만 먼저 deadlock이 무엇인지 이해해야 합니다.
dead lock:채널에서 데이터를 읽거나 쓰려고 했을 때 데이터가 없는 경우. 따라서 이는 goroutine의 현재 실행을 블록하고 다른 goroutine에게 컨트롤을 넘겨줍니다. 하지만 다른 goroutine이 사용 가능하지 않거나 다른 goroutine이 잠들어 있을 때, 이 상황으로 인해 프로그램이 충돌합니다. 이 현상을 dead lock이라고 합니다. 아래의 예제와 같이 보여줍니다:
package main func main() { //채널 생성 //goroutine이 쓰지 않기 때문에 dead lock이 발생합니다 //따라서 select 문이 영원히 블록됩니다 c := make(chan int) select { case <-c: } }
출력:
fatality error: all goroutines are asleep - deadlock! goroutine 1 [채널 수신]: main.main()
이러한 상황을 피하기 위해 select 문에서 default case를 사용합니다. 다시 말해, 프로그램에 dead lock이 발생할 때 select 문의 default 상황을 실행하여 dead lock을 피합니다. 아래의 예제와 같이, select 문에서 default 상황을 사용하여 dead lock을 피합니다.
package main import "fmt" func main() { //채널 생성 c := make(chan int) select { case <-c: default: fmt.Println("!.. Default case..!") } }
출력:
!.. Default case..!
select 문이 nil 채널만 있을 때도 default 상황을 사용할 수 있습니다. 아래의 예제와 같이, 채널 c가 nil이므로 default 상황에서 실행됩니다. 여기의 default 상황이 사용할 수 없다면 프로그램이 영원히 블록되고 dead lock이 발생합니다.
package main import "fmt" func main() { //채널 생성 var c chan int select { case x1 := <-c: fmt.Println("Value: ", x1) default: fmt.Println("Default case..!") } }
출력:
Default case..!