猿问

在比较两个单独的 goroutine 中的两个切片并使用 sync.Waitgroup

我正在学习goroutines,并在两个goroutines中相互比较两个切片,这是在无限循环中永远比较它,这可能不是最好的例子,我无法弄清楚为什么它被挂起。


for ;; {

    var wg sync.WaitGroup

    wg.Add(2)

    go FindinFirst(&Arr1, &Arr2, AddChan, &wg)

    go FindinSecond(&Arr2, &Arr1, DelChan, &wg)

    counter := 0

        for ; ; {

            select {

            case Add, ok := <- AddChan:

                if ok == true {

                    for k, v := range Add  {

                        fmt.Println(k, ":", v)

                    }

                }else {

                    counter += 1

                }

            case Del, ok := <- DelChan:

                if ok == true {

                    for k, v := range Del  {

                        fmt.Println(k, ":", v)

                    }

                }else {

                    counter += 1

                    }

            }

            if counter == 2{

                break

            }

            wg.Wait()

}

函数 FindinFirst 是


func FindinFirst(Arr1, Arr2 *[]string, AddChan chan string, wg *sync.WaitGroup){

defer wg.Done()

fmt.Println("Starting FindinFirst")

defer close(AddChan)

for _, i := range *Arr1 {

    if IfExists(i, *Arr2) {

        fmt.Println("Exists")

        continue

    } else {

        AddChan <- i


    }

}

}

函数 FindinSecond 是


func FindinSecond(Arr2, Arr1 *[]string, DelChan chan string, wg *sync.WaitGroup){

defer wg.Done()

fmt.Println("Starting FindinSecond")

defer close(DelChan)

for _, i := range *Arr2 {

    if IfExists(i, *Arr1) {

        fmt.Println("Exists")

        continue

    } else {

        DelChan <- i


    }

}

}

并且IfExists只是一个函数,如果值存在于切片中,则返回一个布尔值。


但是,该例程只打印一个值,我不确定为什么会发生这种情况。两个切片都有接近 1000 个值,并且都具有唯一性。代码有什么问题?


Cats萌萌
浏览 107回答 1
1回答

呼如林

我不认为在这里使用等待组有任何用处...由于您正在使用 for 循环内的通道,所以 putwg.wait()将阻塞,直到所有等待组都完成。在这种情况下,除非有人在等待,否则将值放入 AddChan 将被阻止。该代码仅适用于第一种情况,之后它会挂起。您可以删除wg.wait()for 循环和外部 for 循环,它会起作用。func main() {&nbsp; &nbsp; Arr1 := []string{"a", "b", "c", "d"}&nbsp; &nbsp; Arr2 := []string{"c", "e", "f", "g"}&nbsp; &nbsp; AddChan := make(chan string)&nbsp; &nbsp; DelChan := make(chan string)&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; wg.Add(2)&nbsp; &nbsp; go FindinFirst(&Arr1, &Arr2, AddChan, &wg)&nbsp; &nbsp; go FindinSecond(&Arr2, &Arr1, DelChan, &wg)&nbsp; &nbsp; counter := 0&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case Add, ok := <-AddChan:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ok == true {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fmt.Println(Add)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; counter += 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; case Del, ok := <-DelChan:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ok == true {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(Del)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; counter += 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; //if both the channels are closed, we are good, hence exit&nbsp; &nbsp; &nbsp; &nbsp; if counter == 2 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Go
我要回答