在两个单独的 goroutine 中比较两个切片并使用 sync.Waitgroup 时挂起 goroutines
Hung goroutines when comparing two slices in two separate goroutines and using 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
只是一个函数,如果该值存在于切片中,则 return 为布尔值。
但是,该例程只停留在一个正在打印的值上,我不确定为什么会这样。这两个切片都有接近 1000 个值,并且都有唯一性。代码有什么问题?
我认为在这里使用等待组没有任何用处...因为您在 for 循环中使用通道,所以放置 wg.wait()
将阻塞直到所有等待组完成。
在这种情况下,将一个值放入 AddChan 将会阻塞,除非有人在等待它。该代码仅适用于第一种情况,之后会挂起。
您可以删除 wg.wait()
和外部 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
}
}
}
我在学习 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
只是一个函数,如果该值存在于切片中,则 return 为布尔值。
但是,该例程只停留在一个正在打印的值上,我不确定为什么会这样。这两个切片都有接近 1000 个值,并且都有唯一性。代码有什么问题?
我认为在这里使用等待组没有任何用处...因为您在 for 循环中使用通道,所以放置 wg.wait()
将阻塞直到所有等待组完成。
在这种情况下,将一个值放入 AddChan 将会阻塞,除非有人在等待它。该代码仅适用于第一种情况,之后会挂起。
您可以删除 wg.wait()
和外部 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
}
}
}