티스토리 뷰

go

Go 채널(Channels)

까오기 2024. 7. 12. 10:25

Go에서 채널(Channels)은 고루틴(Goroutines) 간에 데이터를 주고받을 수 있는 파이프라인을 제공합니다. 채널을 통해 고루틴은 안전하고 쉽게 통신할 수 있으며, 동기화 문제를 해결할 수 있습니다.

채널의 기본 개념

채널은 데이터를 보내고 받을 수 있는 타입 안전한 큐(queue)로, 두 고루틴 간의 통신을 가능하게 합니다. 채널은 chan 키워드를 사용하여 생성됩니다.

채널 생성

채널을 생성하는 방법은 다음과 같습니다:

ch := make(chan int) // int 타입의 채널 생성

채널에 데이터 보내기 및 받기

채널을 통해 데이터를 보내고 받는 방법은 다음과 같습니다:

데이터 보내기

ch <- value // value를 채널 ch로 보냄

데이터 받기

value := <-ch // 채널 ch로부터 데이터를 수신하고 value에 저장

예제: 간단한 채널 사용

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int)

    go func() {
        ch <- 42 // 채널로 데이터 보내기
    }()

    value := <-ch // 채널로부터 데이터 받기
    fmt.Println(value)
}

위 예제에서 고루틴은 채널 ch에 42를 보냅니다. 메인 고루틴은 채널 ch로부터 데이터를 받아 출력합니다.

버퍼링된 채널

채널은 버퍼링될 수 있습니다. 버퍼링된 채널은 버퍼 크기만큼 데이터를 수신자가 준비되지 않았더라도 보낼 수 있습니다.

버퍼링된 채널 생성

ch := make(chan int, 2) // 버퍼 크기가 2인 채널 생성

예제: 버퍼링된 채널

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int, 2)
    ch <- 1
    ch <- 2

    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

위 예제에서 버퍼 크기가 2인 채널을 생성하고, 두 개의 값을 보낸 후 두 개의 값을 받습니다.

채널 닫기

채널을 닫으면 더 이상 데이터를 보낼 수 없습니다. 그러나 닫힌 채널로부터 여전히 데이터를 받을 수 있으며, 모든 데이터를 받은 후에는 채널이 닫혔음을 알 수 있습니다.

예제: 채널 닫기

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int)

    go func() {
        for i := 0; i < 5; i++ {
            ch <- i
        }
        close(ch) // 채널 닫기
    }()

    for i := range ch {
        fmt.Println(i)
    }
}

위 예제에서 고루틴은 5개의 값을 채널에 보내고 채널을 닫습니다. 메인 고루틴은 range를 사용하여 채널로부터 모든 값을 받습니다.

select 문

select 문은 여러 채널 연산을 기다리는 데 사용됩니다. 이는 복잡한 동기화 문제를 해결하는 데 유용합니다.

예제: select 문 사용

package main

import (
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)

    go func() {
        time.Sleep(1 * time.Second)
        ch1 <- "one"
    }()

    go func() {
        time.Sleep(2 * time.Second)
        ch2 <- "two"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-ch1:
            fmt.Println("Received", msg1)
        case msg2 := <-ch2:
            fmt.Println("Received", msg2)
        }
    }
}

 

위 예제에서 두 개의 고루틴이 각각 1초와 2초 후에 값을 채널에 보냅니다. 메인 고루틴은 select 문을 사용하여 두 채널 중 어느 하나로부터 값을 수신할 때까지 기다립니다.

채널 활용 예제

작업 분산

채널을 사용하여 작업을 여러 고루틴에 분산할 수 있습니다.

package main

import (
    "fmt"
    "sync"
)

func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    for j := range jobs {
        fmt.Printf("worker %d started job %d\n", id, j)
        results <- j * 2
        fmt.Printf("worker %d finished job %d\n", id, j)
    }
}

func main() {
    jobs := make(chan int, 100)
    results := make(chan int, 100)
    var wg sync.WaitGroup

    for w := 1; w <= 3; w++ {
        wg.Add(1)
        go worker(w, jobs, results, &wg)
    }

    for j := 1; j <= 5; j++ {
        jobs <- j
    }
    close(jobs)

    wg.Wait()
    close(results)

    for result := range results {
        fmt.Println(result)
    }
}

결과 

worker 3 started job 1
worker 3 finished job 1
worker 3 started job 4
worker 3 finished job 4
worker 3 started job 5
worker 3 finished job 5
worker 2 started job 3
worker 2 finished job 3
worker 1 started job 2
worker 1 finished job 2
2
8
10
6
4

위 예제에서 3개의 워커 고루틴이 5개의 작업을 수행하고 결과를 출력합니다.

요약

  • 채널: 고루틴 간의 통신을 위한 파이프라인.
  • 버퍼링된 채널: 수신자가 준비되지 않았더라도 데이터를 보낼 수 있음.
  • 채널 닫기: 더 이상 데이터를 보낼 수 없지만, 닫힌 채널로부터 여전히 데이터를 받을 수 있음.
  • select 문: 여러 채널 연산을 기다리는 데 사용됨.
  • 작업 분산: 채널을 사용하여 작업을 여러 고루틴에 분산 가능.

채널은 Go에서 고루틴 간의 안전한 통신과 동기화를 위한 강력한 도구로, 이를 잘 활용하면 병렬 처리를 효율적으로 구현할 수 있습니다.

 

GIT : https://github.com/kkaok/study-golang/tree/master/src/example/channel

 

study-golang/src/example/channel at master · kkaok/study-golang

Contribute to kkaok/study-golang development by creating an account on GitHub.

github.com

 

출처 : chatGPT

'go' 카테고리의 다른 글

Go Http GET 요청  (0) 2024.07.16
Go 파일 읽고 쓰기  (0) 2024.07.16
Go루틴(goroutine)  (0) 2024.07.12
Go defer, panic, recover  (0) 2024.07.11
Go 에러, 에러처리  (0) 2024.07.11
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함