Our training paths
Grow your skills
You’ll get our FREE Video Series & special offers on upcoming training events along with notifications on our latest blog posts.
Valid email required.
Submit failed. Try again or message us directly at email@example.com.
Check your email for confirmation.
IntroductionWhen new people join the Go-Miami group they always write that they want to learn more about Go’s concurrency model. Concurrency seems to be the big buzz word around the language. It was for me when I first started hearing about Go. It was Rob Pike’s Go Concurrency Patterns video that finally convinced me I needed to learn this language.To understand how Go makes writing concurrent programs easier and less prone to errors, we first need to understand what a concurrent program is and the problems that result from such programs. I will not be talking about CSP (Communicating Sequential Processes) in this post, which is the basis for Go’s implementation of channels. This post will focus on what a concurrent program is, the role that goroutines play and how the GOMAXPROCS environment variable and runtime function affects the behavior of the Go runtime and the programs we write.Processes and ThreadsWhen we run an application, like the browser I am using to write this post, a process is created by the operating system for the application. The job of the process is to act like a container for all the resources the application uses and maintains as it runs. These resources include things like a memory address space, handles to files, devices and threads.A thread is a path of execution that is scheduled by the operating system to execute the code we write in our functions against a processor. A process starts out with one thread, the main thread, and when that thread terminates the process terminates. This is because the main thread is the origin for the application. The main thread can then in turn launch more threads and those threads can launch even more threads.The operating system schedules a thread to run on an available processor regardless of which process the thread belongs to. Each operating system has its own algorithms that make these decisions and it is best for us to write concurrent programs that are not specific to one algorithm or the other. Plus these algorithms change with every new release of an operating system, so it is dangerous game to play.Goroutines and ParallelismAny function or method in Go can be created as a goroutine. We can consider that the main function is executing as a goroutine, however the Go runtime does not start that goroutine. Goroutines are considered to be lightweight because they use little memory and resources plus their initial stack size is small. Prior to version 1.2 the stack size started at 4K and now as of version 1.4 it starts at 8K. The stack has the ability to grow as needed.The operating system schedules threads to run against available processors and
the Go runtime schedules goroutines to run within a logical processor that is bound to a
single operating system thread. By default, the Go runtime allocates a single
logical processor to execute all the goroutines that are created for our program. Even with
this single logical processor and operating system thread, hundreds of thousands of goroutines can be
scheduled to run concurrently with amazing efficiency and performance. It is not recommended to add more that one logical processor, but if you want to run goroutines in parallel, Go provides the ability to add more via the GOMAXPROCS environment variable or runtime function.Concurrency is not Parallelism. Parallelism is when two or more threads are
executing code simultaneously against different processors. If you configure the
runtime to use more than one logical processor, the scheduler will distribute goroutines
between these logical processors which will result in goroutines running on different operating system threads.
However, to have true parallelism you need to run your program on a machine with
multiple physical processors. If not, then the goroutines will be running concurrently against
a single physical processor, even though the Go runtime is using multiple logical processors.Concurrency ExampleLet’s build a small program that shows Go running goroutines concurrently. In this example we are running the code with one logical processor:
We have taught Go to thousands of developers all around the world since 2014. There is no other company that has been doing it longer and our material has proven to help jump start developers 6 to 12 months ahead of their knowledge of Go. We know what knowledge developers need in order to be productive and efficient when writing software in Go.
Our classes are perfect for both experienced and beginning engineers. We start every class from the beginning and get very detailed about the internals, mechanics, specification, guidelines, best practices and design philosophies. We cover a lot about "if performance matters" with a focus on mechanical sympathy, data oriented design, decoupling and writing production software.
Interested in Ultimate Go Corporate Training and special pricing?
Our courses have been designed from training over 4,000 engineers since 2013 and they go beyond just being a language course. Our goal is to challenge every student to think about what they are doing and why.
Please fill out the form below and we'll get back to you soon.
Check your email for confirmation of your sent message. We'll get back to you shortly.
Ardan Labs Copyrights © 2022