GO Lang – Go 루틴 2/4 (채널)

채널

Go 루틴 끼리 데이터를 주고 받기 위해 사용하는 통신 메커니즘

채널생성 규칙

1. 원소타입(element type)

각 채널마다 특정한 데이터 타입으로만 데이터를 교환할 수 있다.

2. 채널로 데이터를 보내는 상대방이 있어야 한다.

채널을 새로 선언하는 문장은 chan 키워드로 표시하고 , 채널을 닫으로면 close() 함수를 호출해야 한다.

3. 채널을 함수의 매개변수로 사용할 시 채널의 방향 표시

데이터를 보낼 채널인지, 받을 채널인지 명시해야 한다.

채널에 데이터 쓰기

package main 

import ( "fmt" "time" ) 

func writeToChannel(c chan int, x int){ 
   fmt.Println(x) 
   c <- x close(c) 
   fmt.Println(x) 
} 
func main(){ 
   c := make(chan int) 
   go writeToChannel(c, 10)
   time.Sleep(1*time.Second) 
}
  • c 라는 채널에 쓴 값을 아무도 읽지 않기 때문에 writeChannel() 함수의 실행은 c <- x 라는 문자에서 막혀 버린다.
  • time.Sleep(1 * time.Second) 라는 문장이 끝나면 프로그램은 더 이상 writeChannel()을 기다리지 않고 종료 한다.

채널에서 데이터 읽기

package main 

import( 
   "fmt" 
   "go/ast" 
   "time" 
) 

func writeToChannel(c chan int, x int){ 
   fmt.Println("1",x) 
   c <- x close(c) 
   fmt.Println("2",x) 
} 

func main(){ 
   c := make(chan int) 
   go writeToChannel(c, 10) 
   time.Sleep(1 * time.Second) 
   fmt.Println("Read:", <-c) 
   time.Sleep(1 * time.Second) 
   _, ok := <-c 
   if ok{ 
      fmt.Println("Channel is open!") 
   }else{ 
      fmt.Println("Channel is close!") 
   } 
}
 
$ go run readCh.go 
1 10 
Read: 10 2 10 
Channel is close! 

$ go run readCh.go 
1 10 2 10 
Read: 10 
Channel is close!
  • <-c 라는 표현을 통해 채널에서 데이터를 읽도록 지정했다.
  • 값을 출력하지 않고 변수 k 에 저장하고 싶다면 k := <-c 와 같이 사용하면 된다.
  • writeToChannel go 루틴 실행
  • writeToChannel에서 채널에 데이터 쓰기 ( c <- x)
  • main 에서 데이터 읽기 ( <-c)
package main 

import ( 
   "fmt"
   "time" 
) 

func main(){ 
   done := make(chan bool) 
   count :=3 
   go func(){ 
      for i := 0; i < count; i++{ 
         time.Sleep(2 * time.Second) 
         done <- true 
         fmt.Println("고루틴 : ", i) 
      } 
   }() 
   for i := 0; i < count ; i++{ 
      <- done fmt.Println("메인함수 : ", i) 
   } 
}
  • Go 루틴 for 실행(0) -> 채널에 데이터 쓰기
  • main for 실행(0) -> 채널에서 데이터 읽기(Go 루틴에서 데이터 쓰기까지 대기)
  • Go 루틴 for 실행(1) -> 채널에 데이터 쓰기
  • main for 실행(1) -> 채널에서 데이터 읽기(Go 루틴에서 데이터 쓰기까지 대기)
  • Go 루틴 for 실행(2) -> 채널에 데이터 쓰기
  • main for 실행(2) -> 채널에서 데이터 읽기(Go 루틴에서 데이터 쓰기까지 대기)

함수 매개변수로 지정한 채널

func f1(c chan int, x int){ 
   fmt.Println("1",x) 
   c <- x 
} 

func f2(c chan<- int, x int){ 
   fmt.Println("1",x) 
   c <- x 
}
  • f1() , f2() 는 같은 역활을 하지만 f2() 함수에서 매개변수에 쓰기전용 채널이이라고 명시함 (c chan<- int)
  • 채널에 데이터를 쓰기
  • 채널에 데이터 읽기(<-c)를 하면 에러 발생

답글 남기기