Concurrency in Go
There are some points that I would like to note down for concurrency in Go.
Go provides:
- concurrent execution (goroutines)
- synchronization (channels)
- multi-way concurrent control (select)
Concurrency is about dealing with lots of things at once, Parallelism is about doing lots of things at once. One is about structue, one is about execution.
-
Concurrency is way to structure a program by breaking it into pieces that can be executed independently.
-
Communication is the means to coordinate the independent executions.
Goroutines is a function running independently in the same address space as other goroutines.
GOROUTINES ARE NOT THREADS!!
- They’re a bit like threads, but they’re much cheaper.
- Goroutines are multiplexed onto OS threads as required.
- When goroutines blocks, that thread blocks but no other goroutine is blocked.
Channels are typed values that allows goroutines to synchronize and exchange information.
The select statement is like a switch, but the decision is based on the ability to communicate rather than equal values.
Concurrent Programming
Concurrent programming in many envs is made difficult by the subtleties required to implement correct access to shared variables.
Go encourages a different approach in which shared values are passed aroung on channels and in fact never actively shared by separate threads of execution. Only one goroutine has access to the value at a given time. Data race cannot occur, by design.
DO NOT communicate by sharing memory; instead share memory by communicating
Goroutines
They’re called goroutines because the existing terms - threads, coroutines, processes and so on convey inaccurate annotations.
A goroutine has a simple model; it is function executing concurrently with other goroutines in the same address space. It is lightweight, costing little more than the allocation of stack space. And stacks start small so they are cheap and grow by allocating(and freeing) heap storage as required.
Goroutines are multiplexed onto multiple OS threads, so if one should block, such as while waiting for I/O, others continue to run. Their design hides many of the complexities of thread creation and management.
A “go” statement start the execution of a function call as an independent concurrent thread of control or goroutine within same address space.
go foo()
The function value and parameter are evaluated as usual in calling goroutines but unlike with regular call, program execution doesn’t wait for the invoked function to compute. Instead the function begins executing independently in a new goroutine. When the function terminates, it’s goroutines also terminates. If the function has any return values, they are discarded when function completes.
Channels
In functions you can specify:
send channel
c chan <- int
- you can push values to the channels
- you can’t receive/pull/read from channel
- you can only push values to the channels
receiver channel
c <- chan int
- you can recieve values from the channel
- a receive channel parameter
- in func, you can pull values from the channel
- you can’t close a receive channel