簡體   English   中英

帶通道的 WaitGroup

[英]WaitGroup with Channels

我一直在玩這個並想出了:

type Function struct{
    Function func(*TaskGroup, []interface{})
    Args []interface{}
}

type TaskGroup struct{
    Group sync.WaitGroup
    Functions []Function
}

func (x *TaskGroup) Start() {
    for _, Function := range x.Functions{
        x.Group.Add(1)
        go Function.Function(x, Function.Args)
    }
    x.Group.Wait()
}

為了更輕松地使用多個函數,我必須等待。

以下測試將起作用,我不明白為什么:

func auxC(x *TaskGroup, args []interface{}){
    defer x.Group.Done()
    messageOut := args[0].(chan string)
    messageOut <- "TestC"
}
func auxD(x *TaskGroup, args []interface{}){
    defer x.Group.Done()
    messageOut := args[0].(chan string)
    messageOut <- "TestD"
}

func TestTaskGroupBaseB(t *testing.T) {
    messageC := make(chan string, 1)
    messageD := make(chan string, 1)

    tg := TaskGroup{
        Functions: []Function{
            {auxC, []interface{}{messageC}},
            {auxD, []interface{}{messageD}},
        },
    }
    tg.Start()

    fmt.Println(<- messageC)
    fmt.Println(<- messageD)

    time.Sleep(100 * time.Millisecond)
}

我首先嘗試使用這樣的無緩沖通道:

messageC := make(chan string)
messageD := make(chan string)

但這不起作用,它只是永遠卡住而不做任何事情,所以我有幾個問題:

  1. 為什么大小為 1 的緩沖通道可以工作,而無緩沖通道卻不能?
  2. 默認大小 1 不是無緩沖的嗎?

重構代碼,見注釋:

主要/測試:

func auxC(args []interface{}){
    messageOut := args[0].(chan string)
    messageOut <- "TestC"
}
func auxD(args []interface{}){
    messageOut := args[0].(chan string)
    messageOut <- "TestD"
}

func TestTaskGroupBaseB(t *testing.T) {
    messageC := make(chan string,1)
    messageD := make(chan string,1)

    tg := TaskGroup{
        Functions: []Function{
            {auxC, []interface{}{messageC}},
            {auxD, []interface{}{messageD}},
        },
    }
    tg.Wait()

    fmt.Println(<- messageC)
    fmt.Println(<- messageD)

    time.Sleep(100 * time.Millisecond)
}

任務組:

type Function struct{
    Function func([]interface{})
    Args []interface{}
}

type TaskGroup struct{
    Group sync.WaitGroup
    Functions []Function
}

func (x *TaskGroup) Wait() {
    for _, function := range x.Functions{
        x.Group.Add(1)
        go func(x *TaskGroup, f Function){
            defer x.Group.Done()
            f.Function(f.Args)
        }(x, function)
    }
    x.Group.Wait()
}

使用緩沖區大小為 1 的通道,首先寫入緩沖區數據,然后 goroutines 結束,您可以在主 goroutine 中讀取緩沖區數據。

當通道大小為零時,對通道的寫入會阻塞,直到另一個 goroutine 從中讀取。 所以你的兩個 goroutine 都在等待寫入通道。 如果在通道讀入 main 之后移動 Wait() 調用,它應該可以工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM