On the goroutine
But the point is that Go gives you concurrency, a concurrency specifically suited to modern systems programming. It gives you concurrency that runs close the metal, but it also gives you a new breed of concurrency you won't find in other languages, including Erlang. And this comes from goroutines.
Goroutines aren't threads or lightweight threads. They aren't callbacks. They're processes within a single address space that can communicate with each other. Communication is provided by "channels" running between goroutines, and these channels can transmit multiple signals at once. You can use a channel to send any variable, including other channels.
These processes can run across multiple operating system threads, but crucially, they can also run within threads, letting you handle myriad tasks with a relatively small memory footprint. "The idea is that goroutines time-slice on OS threads, so you can have any number of goroutines being serviced by a smaller number of OS threads, and the Go runtime is smart enough to realize which of those goroutines is blocking something and go off and do something else," Ketelsen says.
"It's using the runtime to 'multitask' using fewer OS resources. Goroutines are much lighter than a thread. You can have many thousands of them running without taking a performance hit."
This is ideal, Rob Pike says, for something like a web server, something that talks to many thousands of clients. "Linux, for many years, had very bad thread support. It wasn't practical to use thread-per-request model for web servers. Threads are so heavy. They require so much space in memory. But it's practical to use a goroutine-per-request model," he explains.
"Goroutines use very small kilobytes of memory and yet they can represent the entire application stream of a client action inside the server. ... You can imagine tens of thousands of goroutines running in a server. We've run benchmarks with tens of thousands of goroutines, and they run very efficiently."
What's more, the channel setup is conducive to communication across a network. Pike points to a channel's ability to send a channel – something akin to, say, a phone call sending a phone call. This is a particularly nice way, Pike says, of building a multiplexer. "When I send a request to the service at the other end of the channel, I can include in that request a channel that only I know about, so the server has to respond only to me."
"That lets you halve the amount of muxing you need to do. You use a mux to get to the service, but then the service has a direct channel back to you. It just returns the answer back to you. You don't have to send that back through the mux."
Go's concurrency setup, Keith Rarick says, mapped perfectly to Heroku's Doozer project. Paxos, the algorithm at the heart of Chubby, operates using independent and concurrent processes that pass each other messages. With Doozer, those processes become goroutines, and messages are passed via channels. "These tools let us avoid complex bookkeeping and stay focused on the problem at hand," Keith Rarick and Blake Mizerany said in a recent blog post. "We are still amazed at how few lines of code it took to achieve something renowned for being difficult."
This is exactly the sort of thing Go was designed for. And presumably, Google is using the language for similar purposes. In May of 2010, Rob Pike announced that the company was using Go for "some production" stuff, but he declined to provide specifics. And he still declines to provide specifics. "Go is being used for lots of things," he tell us. Andrew Gerrand, another member of the Go team, says the language is being used on a "small number of Google systems", and in all likelihood, these systems play a role in the distributed infrastructure that spans Google's worldwide network of data centers.