This article has participated in the weekend study program, click to see more details

  1. Imagine a scenario where you now have 10 tasks that you want to execute in parallel. It’s easy, right? Just use the coroutine go.
Package main func main() {someUnhandledItems := []int64{1,2,3,4,5,6,7,8,9,10} i := range someUnhandledItems { go handleItem(i) } } func handleItem(item int64) { log.Println("item is : ", item) }Copy the code
  1. I’ll do it here and I’ll see why there’s no output from the console. The reason is that main is also a coroutine, and since main exits before the handleItem function completes, the function that goes out doesn’t return. This can be done with waitGroup.
Package main import (" FMT ""sync") var wg sync.waitgroup func main() {someUnhandledItems := [] int64,2,3,4,5,6,7,8,9,10 {1} for _, i := range someUnhandledItems { wg.Add(1) go handleItem(i) } wg.Wait() } func handleItem(item int64) { defer wg.Done() log.Println("item is : ", item) }Copy the code
  1. We can get the results this time. However, there is also a requirement that a maximum of 3 tasks can be executed at one time, i.e. the number of concurrent tasks is 3.
Package main import (" FMT ""sync") var wg sync.waitgroup var maxConcur = 3 func main() {ch := make(chan struct{}, MaxConcur) someUnhandledItems := []int64{1,2,3,4,5,6,7,8,9,10} for _, i := range someUnhandledItems { wg.Add(1) ch <- struct{}{} go handleItem(i,ch) } wg.Wait() } func handleItem(item int64,ch chan struct{}) { defer wg.Done() log.Println("item is : ", item) <- ch }Copy the code

Well, I’m done! Seems to fit the bill. But take a closer look? If you can’t tell, run it and try it. You see what’s wrong? Something’s wrong. Wg.add (1) is in the right position? If not, how to modify?

Package main import (" FMT ""sync") var wg sync.waitgroup var maxConcur = 3 func main() {ch := make(chan struct{}, MaxConcur) someUnhandledItems := []int64{1,2,3,4,5,6,7,8,9,10} for _, i := range someUnhandledItems { ch <- struct{}{} go handleItem(i,ch) } wg.Wait() } func handleItem(item int64,ch chan struct{}) { wg.Add(1) defer wg.Done() log.Println("item is : ", item) <- ch }Copy the code

That’s fine. Again, are we sure we’re good? If handleItem is a very complex function, should I add error to the return? If a panic occurs on the handleItem, can you catch it? How to solve the two problems mentioned above? Welcome to discuss, and see you tomorrow at ❤️