Go 채널 패턴 - 팬아웃 세마포어

Go 프로그래밍 기술을 향상하고 더 나은 Go 엔지니어가 되기 위해 최근 Ardan Labs에서 우수한 주문형 교육을 구입했습니다. 재료는 Go 전문 엔지니어인 .






아르단 연구소


@ardanlabs






🎙️팟캐스트에 오신 것을 환영합니다! 🎙️엔지니어들은 종종 채용 담당자에 대해 부정적인 인상을 가지고 있지만 때로는 Martin과 같은 특별한 사람을 찾습니다. 의 전문가로서 Martin은 귀하와 귀하의 가족을 위한 최고의 기회를 찾기 위해 최선을 다하고 있습니다 😊


오후 19:01 - 2021년 12월 8일









저는 Go 모범 사례와 설계 철학에 따라 더 관용적인 코드를 작성하는 방법을 배우는 과정을 기록하기로 결정했습니다.

이 게시물 시리즈는 고루틴을 통한 Go의 오케스트레이션/신호에 사용되는 채널 패턴을 설명합니다.

팬아웃 세마포어 패턴



Fan Out Semaphore Pattern의 기본 아이디어는 다음과 같습니다.

  • Fan Out 패턴에 포함된 모든 것:
  • 신호 시맨틱을 제공하는 버퍼링된 채널
  • 일부 작업을 수행하기 위해 여러(하위) 고루틴을 시작하는 고루틴
  • 일부 작업을 수행하고 신호 채널을 사용하여 작업 완료 신호를 보내는 다중(자식) 고루틴



  • PLUS 추가:
  • 실행을 예약할 수 있는 자식 고루틴의 수를 제한하는 데 사용되는 새 세마포어 채널




  • 예시



    팬 아웃 패턴에는 몇 가지 작업이 필요한 여러 개employees가 있습니다.

    또한 작업이 완료되기를 기다리는 manager ( main goroutine)도 있습니다. 각각의 employee 작업이 완료되면 employee는 통신 채널 manager을 통해 신호 (paper )를 전송하여 ch 알립니다.

    Fan Out Semaphore Pattern에는 주어진 순간에 작업을 수행할 수 있는 최대 수employees에 대한 추가 제약이 있습니다.

    설명



    예를 들어 직원이 100명인데 사무실 공간에 빈 자리가 10개밖에 없습니다. 주어진 순간에 10명의 직원을 위한 충분한 공간만 있을 때 100명의 직원이 작업을 수행할 수 있다는 것은 중요하지 않습니다. 나머지 90명의 직원은 10명 중 1명이 작업을 마치고 자리를 비울 때까지 기다려야 합니다.

    이 패턴의 좋은 사용 사례는 일괄 처리입니다. 여기서는 수행할 작업이 어느 정도 있지만 주어진 순간에 활성 실행기의 수를 제한하려고 합니다.

    Go Playground에서 예제를 자유롭게 시도해 보십시오.

    package main
    
    import (
        "fmt"
        "math/rand"
        "time"
    )
    
    func main() {
        emps := 10
    
        // buffered channel, one slot for every goroutine
        // send side can complete without receive (non-blocking)
        ch := make(chan string, emps)
    
        // max number of RUNNING goroutines at any given time
        // g := runtime.NumCPU()
        g := 2
        // buffered channel, based on the max number of the goroutines in RUNNING state
        // added to CONTROL the number of goroutines in RUNNING state
        sem := make(chan bool, g)
    
        for e := 0; e < emps; e++ {
            // create 10 goroutines in the RUNNABLE state
            // one for each employee
            go func(emp int) {
    
                // when goroutine moves from RUNNABLE to RUNNING state
                // send signal/value inside a `sem` channel
                // if `sem` channel buffer is full, this will block
                // e.g. employee takes a seat
                sem <- true
                {
                    // simulate the idea of unknown latency (do not use in production)
                    // e.g. employee does some work
                    time.Sleep(time.Duration(rand.Intn(200)) * time.Millisecond)
    
                    // once work is done, signal on ch channel
                    ch <- "paper"
                    fmt.Println("employee : sent signal : ", emp)
                }
    
                // once all work is done pull the value from the `sem` channel
                // give place to another goroutine to do the work
                // e.g. employee stands up and free up seat for another employee
                <-sem
            }(e)
        }
    
        // wait for all employee work to be done
        for emps > 0 {
            // receive signal sent from the employee
            p := <-ch
    
            emps--
            fmt.Println(p)
            fmt.Println("manager : received signal : ", emps)
    
        }
    }
    


    결과




    go run main.go
    
    employee : sent signal :  9
    paper
    manager : received signal :  9
    employee : sent signal :  4
    paper
    manager : received signal :  8
    employee : sent signal :  1
    paper
    manager : received signal :  7
    employee : sent signal :  2
    paper
    manager : received signal :  6
    employee : sent signal :  3
    paper
    manager : received signal :  5
    employee : sent signal :  8
    paper
    manager : received signal :  4
    employee : sent signal :  6
    paper
    manager : received signal :  3
    employee : sent signal :  5
    paper
    manager : received signal :  2
    employee : sent signal :  0
    paper
    manager : received signal :  1
    employee : sent signal :  7
    paper
    manager : received signal :  0
    


    결론



    이 기사에서는 팬 아웃 세마포어 채널 패턴에 대해 설명했습니다. 또한 간단한 구현이 제공되었습니다.

    자세한 내용은 우수한Ardan Labs 교육 자료를 참조하십시오.

    자원:
  • Ardan Labs
  • Cover image by Igor Mashkov from Pexels
  • Fan out picture
  • 좋은 웹페이지 즐겨찾기