기술나눔

Go 언어---동시 프로그래밍 채널(이중 채널, 단일 채널) 및 응용 사례(생산자 소비자, 프린터 모델)

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

채널

고루틴은 동일한 주소 공간에서 실행되므로 공유 메모리에 대한 액세스는 동기화되어야 합니다.고루틴은 메모리를 공유하는 것이 아니라 통신을 통해 메모리를 공유합니다.

참조 유형 채널은 CSP 모드의 특정 구현이며 다중 고루틴 통신에 사용됩니다. 동시성 안전성을 보장하기 위해 내부적으로 동기화를 구현합니다.

채널 유형

맵과 마찬가지로 채널도 make에 의해 생성된 기본 데이터 구조에 대한 참조입니다.
채널을 복사하거나 함수 매개변수 전달에 사용할 때는 채널 참조만 복사하므로 호출자와 호출 수신자는 동일한 채널 개체를 참조하게 됩니다. 다른 참조 유형과 마찬가지로 채널의 0 값은 nil입니다.
채널을 정의할 때 채널로 전송되는 값의 유형도 정의해야 합니다. 내장된 make() 함수를 사용하여 채널을 생성할 수 있습니다.

make (chan Type)
make (chan Type,capacity)
  • 1
  • 2
  • 용량=0이면 채널이 버퍼링되지 않고 읽기 및 쓰기가 차단됩니다. 용량>0이면 채널에 캐시가 있고 용량 요소가 채워질 때까지 쓰기가 차단되지 않습니다.
  • Chamnel은 <- 연산자를 통해 데이터를 받고 보냅니다. 데이터를 보내고 받는 구문은 다음과 같습니다.
channel<-value   //发送value 到channel
<-channel     //接收并将其丢弃
x:=<-channel   //从 channel 中接收数据,并賦偵给x
x,ok:=<-channel   //功能同上,同时检查通道是否已关闭或者是否为空
  • 1
  • 2
  • 3
  • 4

기본적으로 채널은 데이터를 수신하고 보낼 때 다른 쪽 끝이 준비되지 않은 한 차단되므로 명시적인 잠금 없이도 고루틴 동기화가 더 간단해집니다.

성취하다

여기에 이미지 설명을 삽입하세요.

  • 파이프는 인쇄물 앞쪽에 하나, 인쇄물 뒤쪽에 하나씩 배치됩니다.
  • Person2가 먼저 실행되고 파이프라인에 데이터가 없으면 차단됩니다.
  • Person1이 실행되고 데이터를 인쇄한 후 파이프에 데이터를 입력하면 Person2가 이를 감지하고 인쇄를 시작합니다.

채널을 통해 동기화 및 데이터 상호 작용 구현

여기에 이미지 설명을 삽입하세요.
여기에 이미지 설명을 삽입하세요.

버퍼링되지 않은 채널

버퍼링되지 않은 채널은 값을 수신하기 전에 저장할 수 있는 기능이 없는 채널입니다.
이러한 유형의 채널에서는 전송 고루틴과 수신 고루틴이 동시에 전송 및 수신 작업을 완료할 준비가 되어 있어야 합니다. 두 개의 고루틴이 동시에 준비되지 않은 경우 채널은 보내기 또는 받기 작업을 먼저 수행하는 고루틴을 차단하고 기다리게 합니다.
채널에 대한 전송 및 수신의 상호 작용은 본질적으로 동기식입니다. 어떤 작업도 다른 작업과 독립적으로 존재할 수 없습니다.
다음 그림은 버퍼링되지 않은 채널을 사용하여 두 개의 고루틴이 값을 공유할 수 있는 방법을 보여줍니다.
여기에 이미지 설명을 삽입하세요.

  • 즉, 채널 자체가 물건을 저장할 수는 없으며, 하나에 무언가를 넣으면 즉시 꺼낼 수 있습니다.
  • 1단계에서는 두 고루틴이 모두 채널에 도착하지만 어느 쪽도 전송이나 수신을 시작하지 않습니다.
  • 2단계에서는 왼쪽의 고루틴이 채널에 손을 뻗어 채널에 데이터를 보내는 동작을 시뮬레이션합니다. 이때 고루틴은 교환이 완료될 때까지 채널에 잠겨 있습니다.
  • 3단계에서 오른쪽의 고루틴은 채널에 손을 넣어 채널에서 데이터 수신을 시뮬레이션합니다. 이 고루틴은 교환이 완료될 때까지 채널에 잠겨 있습니다.
  • 4단계와 5단계에서 교환이 발생하고 마지막으로 6단계에서 두 고루틴이 채널에서 손을 떼며 잠긴 고루틴이 해제되는 것을 시뮬레이션합니다. 이제 두 고루틴 모두 다른 작업을 수행할 수 있습니다.

버퍼링되지 않은 채널 생성

make (chan Type)//等价于make (chan Type,0)
  • 1

버퍼 크기가 지정되지 않으면 채널은 동기식이므로 발신자가 보낼 준비가 되고 수신자가 수신할 준비가 될 때까지 차단됩니다.

여기에 이미지 설명을 삽입하세요.

  • ch&lt;-i는 채널에 데이터를 쓰고, 메인 코루틴은 이를 감지할 때까지 실행되지 않습니다. 이때 하위 코루틴도 차단되고 대기합니다. 파이프가 데이터를 읽은 후 하위 코루틴이 계속됩니다. .
  • 그러나 println은 파이프를 읽은 후 데이터를 인쇄하므로 인쇄 속도는 시스템에 의해 결정됩니다.

버퍼링된 채널

버퍼링된 채널은 수신되기 전에 하나 이상의 값을 저장할 수 있는 채널입니다.
이 유형의 채널에서는 고루틴이 전송과 수신을 동시에 완료해야 할 필요가 없습니다. 채널에는 보내기 및 받기 작업을 차단하는 다양한 조건도 있습니다. 수신 작업은 수신할 채널에 값이 없는 경우에만 차단됩니다. 전송 작업은 전송되는 값을 수용할 수 있는 버퍼가 채널에 없는 경우에만 차단됩니다.
이로 인해 버퍼링된 채널과 버퍼링되지 않은 채널 사이에 큰 차이가 발생합니다. 버퍼링되지 않은 채널은 고루틴을 보내고 받는 것이 동시에 데이터를 교환하도록 보장합니다. 버퍼링된 채널에는 그러한 보장이 없습니다.
여기에 이미지 설명을 삽입하세요.

  • 1단계에서 오른쪽의 고루틴은 채널로부터 값을 수신합니다.
  • 2단계에서 오른쪽의 고루틴은 독립적으로 값을 수신하는 작업을 완료하고, 왼쪽의 고루틴은 채널에 새 값을 전송합니다.
  • 3단계에서 왼쪽의 고루틴은 여전히 ​​채널에 새로운 값을 보내고 있는 반면, 오른쪽의 고루틴은 채널에서 다른 값을 수신하고 있습니다. 이 단계의 두 작업은 동기화되지도 않고 서로 차단하지도 않습니다.
  • 마지막으로 4단계에서는 모든 송수신이 완료되었으며 채널에는 아직 몇 가지 값이 남아 있고 더 많은 값을 저장할 공간이 있습니다.

만들다

make (chan Type,capacity)
  • 1

버퍼 용량이 주어지면 채널은 비동기식입니다. 버퍼에 데이터 전송에 사용되지 않는 공간이 있거나 수신 가능한 데이터가 포함되어 있는 한 차단 없이 통신이 진행됩니다.

성취하다

여기에 이미지 설명을 삽입하세요.

  • 3개가 충분히 저장되면 차단하고 읽기를 기다립니다. 기본 코루틴이 데이터 조각을 읽고 여유 공간이 있으면 하위 코루틴이 계속 실행되며 후속 인쇄 순서는 확실하지 않습니다.
    여기에 이미지 설명을 삽입하세요.

채널 닫기

채널은 ok를 사용하여 채널이 아직 열려 있는지 여부를 감지할 수 있습니다. 채널이 닫혀 있으면 데이터를 읽을 수 없습니다.

여기에 이미지 설명을 삽입하세요.

  • num ,ok:=<-ch채널이 닫혀 있는지 감지할 수 있습니다.

알아채다

  • 채널은 파일처럼 자주 닫을 필요가 없습니다. 실제로 전송할 데이터가 없거나 범위 루프 등을 명시적으로 종료하려는 경우에만 채널을 닫으십시오.
  • 채널을 닫은 후에는 더 이상 데이터를 채널로 보낼 수 없습니다(패닉 오류가 발생하여 수신이 즉시 0 값을 반환하게 됨).
  • 채널을 닫은 후에도 계속해서 채널에서 데이터를 수신할 수 있습니다.
  • 채널이 없을 경우 전송 및 수신이 모두 차단됩니다.
    여기에 이미지 설명을 삽입하세요.
  • 범위를 사용하여 채널을 순회하고 자동으로 루프에서 벗어날 수 있습니다.
    여기에 이미지 설명을 삽입하세요.

단방향 채널

기본적으로 채널은 이중 질문입니다. 즉, 데이터를 보내고 받을 수 있습니다.
그러나 매개변수로 전달된 채널을 자주 볼 수 있으며 그 값은 데이터를 전송하거나 데이터를 수신하는 데에만 한 방향으로 사용될 것으로 예상됩니다. 단방향 카멜 변수의 선언은 다음과 같이 매우 간단합니다.

var ch1 chan int //ch1双向
var ch2 chan<-float64 //ch2单向,只能用于写float64数据
var ch3 <-chan int  //ch3单向,只能用于读int数据
  • 1
  • 2
  • 3

chan&lt;-은 데이터가 파이프에 들어가고 데이터가 파이프에 기록되어 호출자에게 출력됨을 의미합니다.
&lt;-chan은 데이터가 파이프에서 나온다는 것을 나타냅니다. 호출자의 경우 파이프에서 데이터를 얻습니다. 이는 당연히 입력입니다.
채널은 묵시적으로 단방향 대기열(수신 전용 또는 송신 전용)로 변환될 수 있지만 단방향 채널은 일반 채널로 변환될 수 없습니다.

여기에 이미지 설명을 삽입하세요.

단일 채널을 활용하여 생산자-소비자 모델 구현

여기에 이미지 설명을 삽입하세요.