Hung goroutines when comparing two slices in two separate goroutines and using sync.Waitgroup
Date : March 29 2020, 07:55 AM
it fixes the issue I don't think there is any use of using wait groups here... Since you are consuming the channels inside a for loop, putting wg.wait() will block untill all the wait groups are completed. In this cases, putting a value into AddChan will block unless some one is waiting for it. The code works just for first case, after which it hangs. 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
}
}
}
|
Why does this WaitGroup sometimes not wait for all goroutines?
Tag : go , By : Debashree
Date : March 29 2020, 07:55 AM
hope this fix your issue The code below outputs 2 sometimes. Why isn't the wait group waiting for all the goroutines to complete ? , There is a race condition in your code. It is right here: go func (i int) {
defer ws.Done()
// race condition on s.Rash access
s.Rash = append(s.Rash, i)
}(i)
// create a global mutex
var mutex = &sync.Mutex{}
// use mutex to prevent race condition
go func (i int) {
defer ws.Done()
defer mutex.Unlock() // ensure that mutex unlocks
// Lock the resource before accessing it
mutex.Lock()
s.Rash = append(s.Rash, i)
}(i)
|
Recursion in golang is giving deadlock or negative WaitGroup counter when using goroutines, channels and sync.Waitgroup
Date : March 29 2020, 07:55 AM
may help you . Short answer : You are not closing the channel. Fix : add defer wg.Done() at beginning of the go routine that calls FindDirs go func() {
defer wg.Done()
filtermounts.FindDirs(parsedConfig.ScanFrom, []int64{filtermounts.EXT4_SUPER_MAGIC}, wg, dirlistchan)
}()
fatal error: all goroutines are asleep - deadlock!
go run filename.go /path/to/folder
package main
import (
"bytes"
"fmt"
"os"
"sync"
"syscall"
)
func main() {
wg := new(sync.WaitGroup)
dirlistchan := make(chan string, 1000)
wg.Add(1)
go func() {
defer wg.Done()
FindDirs(os.Args[1], []int64{61267}, wg, dirlistchan)
}()
go func() {
wg.Wait()
close(dirlistchan)
}()
for i := range dirlistchan {
fmt.Println(i)
}
wg.Wait()
}
func FindDirs(dir string, nativePartitions []int64, wg *sync.WaitGroup, dirlistchan chan string) {
fd, err := os.Open(dir)
if err != nil {
panic(err)
}
filenames, err := fd.Readdir(0)
if err != nil {
panic(err)
}
for _, i := range filenames {
var buff bytes.Buffer
buff.WriteString(dir)
switch dir {
case "/":
default:
buff.WriteString("/")
}
buff.WriteString(i.Name())
/*err := os.Chdir(dir)
if err != nil {
return err
}*/
t := new(syscall.Statfs_t)
err = syscall.Statfs(buff.String(), t)
if err != nil {
//fmt.Println("Error accessing", buff.String())
}
if checkDirIsNative(t.Type, nativePartitions) && i.IsDir() {
dirlistchan <- buff.String()
FindDirs(buff.String(), nativePartitions, wg, dirlistchan) //recursion happens here
} else {
//fmt.Println(i.Name(), "is not native")
}
}
}
func checkDirIsNative(dirtype int64, nativetypes []int64) bool {
for _, i := range nativetypes {
if dirtype == i {
return true
}
}
return false
}
|
Goroutines with sync.WaitGroup end before last wg.Done()
Date : March 29 2020, 07:55 AM
may help you . The last goroutine you spawn—that one intended to collect the results—is not waited by main() so wg.Wait() in there returns, main() quits and reaps the remainin goroutines. Supposedly just a single—collecting—goroutine remains by that time but it fails to update the slice. Also note that due to the same reason you have a data race in your program: by the time main() reads the slice of results, it does not know whether it's safe to read it—that is, whether the writer is done writing to there.
|
WaitGroup goroutines with channel
Tag : go , By : meodudang
Date : March 29 2020, 07:55 AM
it helps some times Right after the latest messages <- 1, the deferred wg.Done() is invoked which releases wg.Wait() in the end of the program and the program quits. When a program quits all the goroutines get killed, so the printing goroutine does not have a chance to print the latest value. If you put something like time.Sleep(time.Second * 1) right after wg.Done() you would be able to see all the output lines.
|