Why does my code work correctly when I run wg.Wait () inside goroutine?

I have a list of URLs that I am reading. What I want to do is save all the successfully cleared page data to the feed, and when I'm done, upload it to the slice. I don’t know how many successful chips I will get, so I can’t specify a fixed length. I expected the code to reach wg.Wait(), and then wait for all methods to wg.Done()be called, but I never reached the instruction close(queue). Looking for a similar answer, I came across this answer SO

stack overflow

where the author does something like this:

ports := make(chan string)
toScan := make(chan int)
var wg sync.WaitGroup

// make 100 workers for dialing
for i := 0; i < 100; i++ {
    wg.Add(1)
    go func() {
        defer wg.Done()
        for p := range toScan {
            ports <- worker(*host, p)
        }
    }()
}

// close our receiving ports channel once all workers are done
go func() {
    wg.Wait()
    close(ports)
}()

As soon as I wrapped my wg.Wait()inside goroutine, it was achieved close(queue):

urls := getListOfURLS()
activities := make([]Activity, 0, limit)
queue := make(chan Activity)
for i, activityURL := range urls {
    wg.Add(1)
    go func(i int, url string) {
        defer wg.Done()
        activity, err := extractDetail(url)
        if err != nil {
            log.Println(err)
            return
        }
        queue <- activity
    }(i, activityURL)
}
    // calling it like this without the goroutine causes the execution to hang
// wg.Wait() 
// close(queue)

    // calling it like this successfully waits
go func() {
    wg.Wait()
    close(queue)
}()
for a := range queue {
    // block channel until valid url is added to queue
    // once all are added, close it
    activities = append(activities, a)
}

close, goroutine wg.Wait()? , defer wg.Done() , , wg.Wait(). ?

+4
2

, goroutines , queue. :

queue := make(chan Activity)
for i, activityURL := range urls {
    wg.Add(1)
    go func(i int, url string) {
        defer wg.Done()
        activity, err := extractDetail(url)
        if err != nil {
            log.Println(err)
            return
        }
        queue <- activity // nothing is reading data from queue.
    }(i, activityURL)
}

wg.Wait() 
close(queue)

for a := range queue {
    activities = append(activities, a)
}

goroutine queue <- activity, queue , . , queue wg.Wait.

wg.Wait , goroutine. , , .

goroutine , queue.

// wg.Wait does not block the main thread.
go func() {
    wg.Wait()
    close(queue)
}()

goroutines queue <- activity ( queue) . wg.Done.

goroutine wg.Wait, queue , .

+4

queue , goroutine, , , . , goroutinte , - wg.Wait . goroutine:

go func() {
    for a := range queue {
        // block channel until valid url is added to queue
        // once all are added, close it
       activities = append(activities, a)
    }
}()

:

wg.Wait() 
close(queue)

, , .

+1

Source: https://habr.com/ru/post/1686858/


All Articles