为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
Cats萌萌 2022-01-04 21:19:16
我正在学习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 个值,并且都具有唯一性。代码有什么问题?
查看完整描述

1 回答

?
呼如林

TA贡献1798条经验 获得超3个赞

我不认为在这里使用等待组有任何用处...由于您正在使用 for 循环内的通道,所以 putwg.wait()将阻塞,直到所有等待组都完成。


在这种情况下,除非有人在等待,否则将值放入 AddChan 将被阻止。该代码仅适用于第一种情况,之后它会挂起。


您可以删除wg.wait()for 循环和外部 for 循环,它会起作用。


func main() {

    Arr1 := []string{"a", "b", "c", "d"}

    Arr2 := []string{"c", "e", "f", "g"}

    AddChan := make(chan string)

    DelChan := make(chan string)


    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 {

               fmt.Println(Add)

            } else {

                counter += 1

            }

        case Del, ok := <-DelChan:

            if ok == true {

                fmt.Println(Del)

            } else {

                counter += 1

            }

        }


        //if both the channels are closed, we are good, hence exit

        if counter == 2 {

            break

        }

    }

}


查看完整回答
反对 回复 2022-01-04
  • 1 回答
  • 0 关注
  • 106 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号