logo
down
shadow

Is it safe to add to a waitgroup from multiple goroutines?


Is it safe to add to a waitgroup from multiple goroutines?

Content Index :

Is it safe to add to a waitgroup from multiple goroutines?
Tag : go , By : terrestrial
Date : November 28 2020, 04:01 AM

help you fix your problem Calling Done from multiple routines is safe and is the recommended usage of WaitGroup per the documentation. The reason to call Add from the goroutine that spawns more routines is not because Add is not thread-safe, it is because of the possibility that code like this:
for ... {
    go func() {
        wg.Add(1)
        defer wg.Done()
        ...
    }()
}
wg.Wait()

Comments
No Comments Right Now !

Boards Message :
You Must Login Or Sign Up to Add Your Comments .

Share : facebook icon twitter icon

Hung goroutines when comparing two slices in two separate goroutines and using sync.Waitgroup


Tag : go , By : zac
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


Tag : recursion , By : new Blackberry devel
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()


Tag : go , By : Mark
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.
Related Posts Related QUESTIONS :
  • How to run for x seconds in a http handler
  • What is the purpose of arbitrary precision constants in Go?
  • How do I get proper parameter names in cgo exported functions?
  • How to pass method as parameter in Go?
  • new vs. {} when struct include interface in Go
  • I have a question about the effect of a sender channel
  • I don't understand the evaluation rule here
  • How to find if type is float64
  • What is correct way to check if rune is in Basic Multilingual Plane?
  • Are all runtime errors recoverable in Go?
  • Traverse an array of pairs
  • Looping through all values of a byte array
  • Return polymorphic type with data member
  • Trying to write a custom rule
  • Difference between Ragel transition actions and state actions
  • Generic function which appends two arrays
  • Is it safe to use the read lock of sync.RWMutex for writing and its write lock for reading if the writes never race with
  • Bound mismatch when drawing buffer to screen (golang.org/x/exp/shiny/screen)
  • How to get images path from golang project file
  • export double quotes using template
  • Can't use txdb with Gormigrate
  • How do I optimise a for loop which makes requests to an API?
  • Why does AWS API Gateway websocket send error
  • cannot use nil as type model.Article in return argument
  • Go defer function return values
  • "Unable to start NATS Server in Go Routine" while testing
  • How to us proxy with chromedp
  • Does Golang Copy the String on Modification/Write?
  • Go - cannot parse nested struct
  • how to upload directories to golang server from html?
  • group [][]string (2D slice) by row value
  • Converting a struct to a tuple slice without reflection
  • Golang project Travis CI Build fails with error `Makefile:15: recipe for target 'test' failed`
  • Go channel not receiving/printing last value sent to channel
  • How could I define a safe division using interface and reflect?
  • How to make one pod communicate with the other pod's localhost
  • Why is strings.Builder is slower than fmt.Sprint for appending string in my test program?
  • How to generate zip / 7z archive on the fly in a HTTP server using Gin?
  • How to upload file which is response of third party API
  • Why does 'go vet' complain only in some versions of Go?
  • Convert a struct interface to an identical struct
  • Go Modules "unknown revision" error when using commit hash
  • Is there an easier way to keep local Go packages updated
  • How to manipulate a map field in a structure with reflect package?
  • VSCode debug not display map values in VARIABLES area when running a golang debugger
  • Why ProxyServer not working on chromedp GO
  • Go plugin - "plugin was built with a different version of package"
  • Go modules: "cannot find module providing package" importing sub package of a dependency
  • Go all goroutines are asleep deadlock
  • Retrieving message body with Gmail API
  • Print value of map referenced by pointer
  • go build mistakes .go/src for go/src in looking for dependencies
  • Await two results concurrently with timeout
  • Parsing strings into different types with common error message in GO
  • go reflect find by structtag
  • What is the difference between reflect.ValueOf() and Value.Elem() in go?
  • What's the meaning of (*DefaultHandler)(nil) where DefaultHandler is a struct?
  • Is there a way to build multiple Go module based projects at once?
  • Tried the monad pattern but still have repetitive error handling
  • Explain me the execution time difference
  • shadow
    Privacy Policy - Terms - Contact Us © scrbit.com