본문 바로가기

Golang

고루틴-채널

만약 익명 함수를 고루틴에서 호출하면 어떻게 될까요?

익명 함수에서 연산한 값이 다른 함수에 전달되기도 전에 프로그램이 종료됩니다.

그리서 '채널'을 사용합니다.


따라서 채널은

- make(chan 데이터타입)과 같은 형식으로 생성합니다.

- 채널의 데이터 송/수신은 '<-'연산자를 사용합니다.

- 채널에 값을 보낼 때는 채널 <- 데이터, 채널에서 값을 받을 때는 <- 채널 입니다. 

- 값을 받을 때 :=이나 =을 이용해 변수에 바로 값을 대입도 됩니다.

- 채널에서 값을 받을 때까지만 대기합니다. 가져온다면 바로 코드를 실행합니다.


채널은 고루틴 사이에서 값을 주고받는 통로 역할을 하고, 송/수신자가 서로를 기다리는 속성때문에

고루틴의 흐름을 제어합니다. 그리고 채널의 데이터를 주고 받을때까지 해당 고루틴을 종료하지 않아

별도의 락을 하지 않고도 데이터를 동기화하는데 사용합니다.


비동기 채널에서는 송/수신이 꼭 일대일 대응을 해야합니다. 따라서 이를 도와주는 버퍼라는 것이 있습니다.

송신 루틴에서 수신루틴으로 데이터를 바로 주는게 아니라 특정 개수의 버퍼를 만들어서

송신자는 버퍼로 데이터를 보내고, 수신자는 버퍼에서 데이터를 가져오게끔 합니다.

- make(chan 데이터타입, 버퍼개수)과 같은 형식으로 생성합니다.


동기 채널은 단순히 송/수신 채널이 여러개여서 송신 루틴과 수신 루틴이 번갈아가면서 실행되는 것을 말합니다.

이 방식을 사용하면 송신자는 수신자가 데이터를 수신할 때까지 대기하고, 수신자는 송신자가 데이터를 송신할 때까지

대기합니다.


루틴에서는 채널을 생성하고 데이터를 송신하기 위해서 수신하는 곳이 명확해야 합니다.

동기 채널에서는 수신 루틴에서, 비동기 채널에서는 버퍼에서 데이터를 수신합니다. 수신하는 곳이 명확해야

무한 대기 상황이 발생하지 않습니다. 수신도 마찬가지로 송신된 데이터가 없으면 무한 대기 상태가 됩니다.

이와 같은 상황을 도와주는 방법은 채널을 닫는 방법입니다.

- close(채널이름)과 같은 형식으로 채널을 닫습니다.

추가로 채널을 닫은 후에 데이터를 채널에 송신하면 에러 메세지와 함께 panic이 발생합니다.

또한 채널의 데이터를 모두 수신하고 또 수신하면 nil값을 반환합니다.


채널의 특징으로는 수신자를 의미하는 '<- 채널이름'은 두개의 값을 반환합니다.

첫번째는 채널데이터, 두번째는 채널의 개폐 여부를 bool값으로 알려줍니다. 열려있으면 true,  닫히면 false입니다.


채널에서도 range를 사용가능하다. 채널의 데이터를 채널에 송신한 데이터의 개수만큼 접근하는 용법이다.

이때, 주의할 점은 range는 송신 채널이 닫히지 않았다면 데이터가 들어올 때까지 계속 대기한다.

따라서 데이터가 들어올 때마다 계속 접근합니다. range문은 닫힌 채널의 데이터를 수신할 때 사용하는 것이 일반적이다.

열린 곳에 한다면 데드락이 발생한다.


루틴 끼리는 송신, 수신이 자유롭다.함수의 매개변수로 채널을 전달한 때는

- (매개변수이름 chan 채널데이터타입)으로 입력한다.

'Golang' 카테고리의 다른 글

프로젝트별 코드  (0) 2019.01.07