Concurrency in Go: Notes (part i)
Memory sharing in practice:
- Variable sharing between goroutines[1]
- Multiple goroutines working together
Where we should allocate memory space:
- Function’s stack
- Main process’ memory (Heap Space)
When we execute a function in a goroutines, the variable cannot exist on main function’s stack, because they have completely different lifecycles.
When the Go compiler realizes that goroutines are sharing memory, it allocates memory in the Heap instead of the stack. Then we say that the variable escaped to the Heap:
- Small cost using memory on the heap
- Heap needs to be cleaned by Go’s garbage collector (it goes through the objects that are no longer referenced by any goroutine and marks the space as free)
- We can see this with
go tool compile -m file.go
Goroutines:
- Con: There is no compiler optimization
- Con: Increased overhead by putting variables on heap
- Pro: Achieves speed up
Inlining:
- Optimization, the compiler replaces the function call with the contents of the function to improve performance.
- Since calling a function has a slight overhead (preparing new function stack, passing input params to stack, making program jump to the instruction of the function) is not used when executing functions in parallel.
Updating shared variables from multiple goroutines:
resp, _ := http.Get(url) // Downloads the web page
defer resp.Body.Close() // closes respose at the end of the function
Waitgroups: they block the execution of a goroutine until certain tasks are completed (instead of using sleep
)
Critical Section: Set of instructions that should be executed without interference. If not, race conditions[2] may arise.
func Goshed()
This function yields the processor away, allowing other goroutines to run. It does not suspend the current goroutine,
so the execution resumes automatically. Note: never rely on this to avoid a race condition.
[1]
count:= 5 //Allocates memory space for an integer variable
go countdown(&count) //Starts a GoRoutine and shares memory at the variable reference
// without the 'go' keyword the program will be secuential
[2] Multiple threads or processes sharing a resource and stepping over each other producing unexpected results.