The use of sync.WaitGroup in collaboration

Scenarios used: When several goroutine s are running at the same time, you need to wait for these processes to complete before doing other operations ...
Scenarios used:
Steps to use:
Examples:
What should be paid attention to when using:

Scenarios used:

When several goroutine s are running at the same time, you need to wait for these processes to complete before doing other operations

Steps to use:

  1. Define an object
    2. Use the Add method of sync.WaitGroup to Add a count to the queue 3. Use the Done method of sync.WaitGroup to notify that a collaboration has completed 4. Use the Wait method of sync.WaitGroup to Wait for the completion of the cooperation process

Examples:

package main import ( "sync" "net/http" "io/ioutil" "fmt" ) func download(i int,wg *sync.WaitGroup, url string) (err error){ res, err := http.Get(url) if err != nil || res.StatusCode != 200 { fmt.Println("Down load erro") return err } data, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println("read failed") return err } ioutil.WriteFile(fmt.Sprintf("picture%d.data", i), data, 0644) wg.Done() return nil } func main() { var wg sync.WaitGroup for i := 0; i<200; i++ { wg.Add(1) go download(i,&wg,"http://www.pptok.com/wp-content/uploads/2012/08/xunguang-9.jpg") } wg.Wait() }

What should be paid attention to when using:

The instance of sync.WaiteGroup used in the code of the collaboration must be a pointer, and the value cannot be passed. If the value is passed, an error will be reported because the reference number is negative. For example, change the above code to the following:

package main import ( "sync" "net/http" "io/ioutil" "fmt" ) func download(i int,wg sync.WaitGroup, url string) (err error){ fmt.Println("start download") res, err := http.Get(url) if err != nil || res.StatusCode != 200 { fmt.Println("Down load erro") return err } data, err := ioutil.ReadAll(res.Body) if err != nil { fmt.Println("read failed") return err } ioutil.WriteFile(fmt.Sprintf("picture%d.data", i), data, 0644) fmt.Println("finish download") wg.Done() return nil } func main() { var wg sync.WaitGroup for i := 0; i<200; i++ { wg.Add(1) go download(i,wg,"http://www.pptok.com/wp-content/uploads/2012/08/xunguang-9.jpg") } fmt.Println("finish!!!") wg.Wait() }

Running this code will result in the following error:

finish download finish download panic: sync: negative WaitGroup counter goroutine 203 [running]: sync.(*WaitGroup).Add(0xc00012e650, 0xffffffffffffffff) /usr/local/go/src/sync/waitgroup.go:74 +0x137 sync.(*WaitGroup).Done(0xc00012e650) /usr/local/go/src/sync/waitgroup.go:99 +0x34 main.download(0xa5, 0x0, 0xa6, 0x68d680, 0x3e, 0xc0000789f0, 0xc0000788d0) /home/chenmei/go/src/test/waitgroup.go:22 +0x359 created by main.main /home/chenmei/go/src/test/waitgroup.go:30 +0xa3 exit status 2

This error is caused by the negative reference count in the process of delivery. The value of sync.WaitGroup passed in the process of delivery forms a copy, so the object used in the process of delivery is actually a copy. Therefore, when the Done method is executed, it is the operation of the copy object, which has no effect on the wg in the main method

3 December 2019, 10:29 | Views: 8432

Add new comment

For adding a comment, please log in
or create account

0 comments