Why Go Routines?
Someone on Reddit was asking for an explanation of why you would use Go routines, and I thought it would be useful to capture my response here in case that’s useful to anyone in the future. Parallelism and concurrency, thought vitally important, seem to be concepts that are sometimes difficult for younger programmers to grasp.
In a typical web service in Go, there is a go routine whose job is to accept new incoming connection requests. In order to immediately be able to accept the next request, it doesn’t actually serve the request, merely accepts it and then hands it off to another go routine from a pool. Because go routines can execute in parallel and concurrently, this pool likely has several go routines waiting. Each go routine can be scheduled to a separate OS thread which will then be scheduled onto the actual processor cores in your machine by the operating system. This allows you to make use of multiple cores in your processor to actually execute / handle multiple requests at the same time (in parallel) without having to run and manage multiple processes or use something like a CGI server in front of your application. It is also likely that your pool will actually have more than the number of cores worth of go routines in it. This is to allow for overlapping communication and computation through concurrency. Let’s say one of your requests needs to fetch data from a database. Usually this involves sending a request over a socket to the database and then waiting several milliseconds or more for the response. That go routine is now just blocked waiting on the response and the processor is sitting idle. With multiple go routines, another go routine that isn’t blocked can be scheduled onto the processor to do compute while the original go routine waits on the communication to complete.
This is just a really basic example of go routines being used for you behind the scenes. On your own, you might use go routines to make requests to two separate external services at the same time instead of one after the other or to have a queue of asynchronous work that can be done like aggregating data and periodically writing it out. Overall, you can use go routines to allow for shorter processing time for a single task by overlapping multiple communications, overlapping communication with computation, or running multiple computations in parallel if the work of the task can be divided nicely. You can also use go routines to increase overall throughput by executing tasks in parallel or interleaving the execution of tasks when one task is idle waiting on something.