English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

고락 기본 튜토리얼

고락 제어 문

고락 함수 & 메서드

고락 구조체

고락 슬라이스 & 배열

고락(고락) 문자열(String)

Golang 포인터

Golang 인터페이스

Golang 병렬

Golang 예외(Error)

Golang 기타Miscellaneous

Go Select 문과 dead lock dead lock

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..!