Golang Study) 채널

생공나온 개발자·2020년 8월 29일
0

채널이란?

  • 고루틴끼리 정보를 교환하고 실행의 흐름을 동기화하기 위한 통로
  • 송/수신자가 서로를 기다리는 속성때문에 고루틴의 흐름을 제어(송신자 : 채널 <- 데이터, 수신자 : <- 채널)
  • 데이터를 주고 받을때 까지 별도의 lock을 하지 않고도 데이터를 동기화 하는데 사용

사용방법?

  • make(chan 데이터타입) 형식으로 생성
  • 채널의 대이터 송/수신은 ‘<-‘연산자를 이용
  • 채널에 값을 보낼 때는 채널 <- 데이터, 채널에서 값을 받을 때는 <- 채널을 이용
  • 값을 받을 때는 :=이나 = 을 이용해 변수에 바로 값을 대입

비동기 채널과 버퍼

・데드락(Deadlock) : 교착상태
-> 둘 이상의 프로세스(함수)가 서로 가진 한정된 자원을 요청하는 경우 발생하는 것으로, 프로세스가 진전되지 못하고 모든 프로세스가 대기 상태가 되는 것을 말함

위 이미지의 c라는 string 형 채널을 생성하고 데이터를 보내고 있는데 데이터를 받는 수신자(수신 루틴)가 없기 때문에 값을 수신할 때까지 무한 대기하는 데드락이 발생했다. 그래서 송/수신을 위한 고루틴을 만들고 수신자와 송신자의 요건을 충족시키면 데드락 상황이 발생하지 않고 프로그램이 실행된다.

버퍼

  • 송/수신자를 연결하는 통로 중간에 데이터를 잠깐 저장할 수 있는 공간

*버퍼를 만드는 형식
make(chan 데이터타입, 버퍼개수)

비동기 채널 버퍼에서 고루틴의 대기 조건

  • 송신 루틴은 버퍼가 가득차면 대기
  1. 보내고 할 일을 함. 보낸 순간 버퍼가 가득찼으면 대기, 버퍼에 빈 공간이 생기면 하던 일 마저 끝냄
  • 수신 루틴은 버퍼에 값이 없으면 대기( 버퍼에 값이 들어올 때까지)

송신자는 수신자가 직접 데이터를 받을 때 까지 대기하지 않고 버퍼에 값을 보내가만 하면 다음 코드를 실행하기 때문에 훨씬 효율이 높아진다.물론 버퍼가 가득차서 가득 차서 더이상 송신할 수 없을 때는 다음 코드를 실행하지 않고 채널에 묶어 버린다.(무한 대기 상태)
또한 main() 함수의 수신 루틴은 한개 받고 한개를 처리할 필요 없이 버퍼에 값이 있으면 바로바로 꺼내 쓴다.
똑같이 더 이상 버퍼에 값이 송신되지 않으면 수신 루틴은 무한 대기 상태가 되고 main()함수에서는 데드락이 발생합니다.따라서 송/수신 채널의 개수를 잘 맞춰줘야한다.

동기 채널

  • 비동기 채널과 상반되는 개념
  • 동기 채널은 단순히 송/수신 채널이 여러개여서 송신 루틴과 수신 루틴이 번갈아가면서 실행되는 것을 의미


동기 채널 방식을 사용하면 송신자는 수신자가 데이터를 수신할 때까지 대기하고, 수신자는 송신자가 데이터를 송신할 때 까지 대기한다. (위 이미지 참조)

채널 닫기

  • 데이터 수신시에 송신된 데이터가 없을 경우에 채녈에서 데이터를 수신하면 무한대기상태가 되는데 채널에 데이터를
    송신한 후 채널을 닫으면 해당 채널로는 더이상 데이터를 송신할 수 없지만 채널이 닫힌 후에 계속 수신이 가능하다

  • 채널을 닫을 때는 close(채널이름)형식을 사용한다

*close없이 실행을 했을 시(데드락 발생)

*close생성 후 실행 시(정상실행)

송신 전용, 수신 전용 채널

  • 데이터 송신 : chan <- 채널데이터타입
  • 데이터 수신 : <- chan 채널데이터타입

  • 송/수신 채널의 활용
    : 채널을 사용하기 위해서는 꼭 해당 루틴에 채널이 있어야 한다

    한 루틴은 채널에 두 데이터를 송신하는 역할을 하고 한 루틴은 채널에 있는 데이터를 수신해서 새로운 채널에 두 데이터를 더한 값을 메인 루틴에 송신한다.

select

  • 하나의 고루틴이 여러 채널과 통신할 때 사용한다.
  • switch문과 거의 흡사한 용법으로 사용 된다.
  • case로 여러 채널을 대기시키고 있다가 실행 가능 상태가 된 채널이 있으면 해당 케이스를 수행

실제 코드를 살펴보자


profile
iOS앱개발, 웹개발을 공부중인 비전공 개발자입니다.

0개의 댓글

관련 채용 정보