Recently, in the face of complex business processing, the need to take multiple results of the value and then assemble, calculate and other operations, summarize the process of using Goroutine

When executing a Goroutine, go does not return a value. In this case, we need to use the special channel of go to get the return value. There are two ways to get a return value from a channel. The first form, which is characteristic of the Go style, is sent to a separate Goroutine for a channel or select channel, which processes the return value of the function. It is also traditional to gather all the return values of the goroutine into the current function and return them uniformly to the calling function.

Send a separate Goroutine handler

package main import ( "fmt" "sync" ) var responseChannel = make(chan string, 15) func HttpGet(url int, Limiter chan bool, wg * sync.waitgroup) {// defer defer wg.done () fmt.println (" HTTP get:", url) responseChannel <- fmt.Sprintf("Hello Go %v", Func ResponseController() {for rc := range responseChannel {fmt.println ("response: ", Rc)}} func main() {// start ResponseController() wg := & sync.waitgroup {} // set the number of concurrent requests to 10 limiter := make(chan bool, 10) for i := 0; i < 99; I ++ {// counter +1 wg.add (1) // concurrency +1 limiter < -true go HttpGet(I, limiter, Wg.wait () fmt.println (" all coroutines completed ")}}Copy the code

The key to this Go style of processing is that you need to create a common pipeline for handling the return value up front. Then define a function that reads the pipe all the time, which needs to be started up in a separate Goroutine.

Finally, when concurrent tasks are executed, the results of each concurrent task are piped to the previously pre-started Goroutine.

Aggregate returns in the current function

package main import ( "fmt" "sync" ) func httpGet(url int,response chan string, limiter chan bool, Wg * sync.waitgroup) {// defer defer to wg.done (); Response < -fmt. Sprintf(" HTTP get: %d", url) // Release a pit bit < -limiter} // return all results, Return func collect(urls []int) []string {var result []string WG := & sync.waitGroup {} // Control the number of concurrent requests to 10 limiter := Make (chan bool, 10) defer close(limiter) // defer channel, ResponseChannel := make(chan string, 20) responseChannel := make(chan string, 20) WgResponse := & sync.waitGroup {} // Start the controller to read the result go func() {// wgResponse counter +1 wgresponse.add (1) // read the result for response ResponseChannel {// result = append(result, response)} Wgresponse.done ()}() for _, url := range urls {// counter +1 Wg.add (1) limiter < -true Go httpGet(url,responseChannel, limiter, wg)} wg.wait () // Channel close(responseChannel) // Wait for wgresponse.wait () // return the aggregate result Return result} func main() {urls := []int{1,2,3,4,5,6,7,8,9,10} result := collect(urls) FMT.Println(result)}Copy the code