M Receivers 1 Sender Closed By 3Party

It needed that the close signal must be made by a third-party goroutine. For such cases, we can use an extra signal channel to notify the sender to close the data channel.

  • 多個接收端, 一個發送端, 但是由第三方gorotine來關閉. (ps : 01_M_Receivers_1_Sender, 由發送端關閉)
  • 需要一個額外的channel 去通知 發送端去關閉 data channel
  • 第三方 goroutine call stop() function
    stop := func(){
      select{
          case closing <-struct{}{}:
              <-closed
          case <-closed:
      }
    }
    
  • Sender 收到 closing 信號 -> return -> run defer function close(closed);close(dataCh);

Exercises

https://go.dev/play/p/yHG4tvWACeY

package main

import (
    "log"
    "math/rand"
    "sync"
    "time"
)

func main() {
    rand.Seed(time.Now().UnixNano())
    log.SetFlags(0)

    // ...
    const Max = 100000
    const NumReceivers = 100
    const NumThirdParties = 15

    wgReceivers := sync.WaitGroup{}
    wgReceivers.Add(NumReceivers)

    // ...
    dataCh := make(chan int)
    closing := make(chan struct{}) // signal channel
    closed := make(chan struct{})

    // The stop function can be called
    // multiple times safely.
    stop := func() {
        select {
        case closing <- struct{}{}:
            <-closed
        case <-closed:
        }
    }

    // some third-party goroutines
    for i := 0; i < NumThirdParties; i++ {
        go func() {
            r := 1 + rand.Intn(3)
            time.Sleep(time.Duration(r) * time.Second)
            stop()
        }()
    }

    // The Sender
    go func() {
        defer func() {
            close(closed)
            close(dataCh)
        }()

        for {
            select {
            case <-closing:
                return
            default:
            }
            select {
            case <-closing:
                return
            case dataCh <- rand.Intn(Max):
            }
        }
    }()

    // Receivers
    for i := 0; i < NumReceivers; i++ {
        go func() {
            defer wgReceivers.Done()

            for value := range dataCh {
                log.Println(value)
            }
        }()
    }
    wgReceivers.Wait()
}
© Kimi Tsai all right reserved.            Updated : 2023-07-12 09:04:54

results matching ""

    No results matching ""

    results matching ""

      No results matching ""