Implementation of goroutines

I have been reading up on concurrency in Go. In particular, I have been wondering about the statement from a presentation by Brad Fitzpatrick:
n, err := io.Copy(dst, src)

  • copies n bytes from dst to src
  • synchronous (blocks)
  • Go runtime deals with making blocking efficient
In virtually all languages I have worked with (Java, Scala, javascript, ...), a call that blocks the execution of the current function also blocks the current thread. The only exception is C# with its rather complex async/await feature implemented in the compiler.

Now in Go, if you make a call that blocks the current execution, you are (usually) only blocking the current goroutine, not a thread. The Go runtime multiplexes goroutines on fewer OS threads.

The question therefore is: What are the fundamental differences in the implementation of goroutines compared to OS threads that make goroutines so much more lightweight?

I have asked this question on the Go mailing list and the members of the Go team (notably Dmitry Vyukov and Ian Lance Taylor) have been incredibly helpful.

The summary is:

  • stack that grows and shrinks on demand
  • smaller context, easier to switch
  • cooperative scheduling at known points is less work (can make assumptions about CPU state)
  • scheduling in user space

Here is the discussion: enjoy!

Note: There are other languages (such as Haskell and Erlang) that also have the concept of lightweight "processes" that allow for blocking calls without blocking OS threads. The concept is sometimes referred to as green threads.

Posted by Martin Konicek on 11:21 AM

3 comments:

Pedro Pedruzzi said...

Thanks for the nice post about go's novel approach to concurrency. It is awesome that go seem to have implemented this very efficiently and it is automatically used on the most frequent blocking situations: socket operations and locking (eg. using in-memory message queues)

It's worth mentioning that this concept is also known as fibers or lightweight threads. Some related links:
await implementation for Java:
https://github.com/electronicarts/ea-async
Fiber implementation for the JVM
http://docs.paralleluniverse.co/quasar/
Fiber implementation for Java
http://www.malhar.net/sriram/kilim/

Martin Konicek said...

Those are very good links, thank you Pedro! Ah yes, I remember hearing the name fibers too. I've been recently using the Hack language at fb which has the async / await feature similar to C#. My guess is the Hack runtime / libraries do something similar to Go under the hood, you can e.g. spawn a 1000 async operations and await all of them.

Blog FastCare said...

Nice i hope you will have many post like this
--------------
i'm providing thay man hinh Xiaomi service, special thay man hinh Xiaomi mi4. Contact with me

Post a Comment