Go notes (Concurrency) 🇬🇧

Go notes (Concurrency) 🇬🇧

- 17 mins

Concurrency in Go

Concurrency in Go, makes Go programming language very unique and attractive compared to other languages, in this section I am going to share the notes which I took when I was watching coursera video series.

If you did not already check previous post on Go, it could be helpful to check it out first.

Specialization serie is Programming with Google Go

Keep in mind that the notes are taken from several resources mainly from the course, however post may include other resources as well, I have referenced them when required, if nothing is referenced then it means, notes are taken from the course.

Paralel Execution

Why use parallel execution

Von Neumann Bottleneck

Speedup without Parallelism

Moore’s Law

Power Wall

Power / Temperature Problem

Dynamic Power

Dennard Scaling

Multi-Core Systems

Concurrent vs Parallel

Concurrent Execution

Concurrency Example

Concurrent Programming

Hiding Latency *(Crucial)

Hardware Mapping

Parallel & Concurrency

Shared Mem

Concurrency Basics

Processes

  1. Registers
    • a. Program counter

Operating System

Scheduling Processes

Scheduler processes

Context Switch

Scheduler processes

Threads and Goroutines

Threads vs. Processes

Threads vs Processes

Goroutines

Process

We can call Goroutines as lightweight threads in Go.

Go Runtime Scheduler

Process

Interleavings

Interleaving

Possible Interleavings

Possible Interleaving

Race Conditions

It is happenning when multiple goroutines try to write/read from a source at the same time, could be prevented using mutex

Possible Interleaving

Communication Between Tasks

Web Server Per Client

Image processing 1 thread per pixel

Goroutines

Goroutines are new way of threading in lightweight approach.

Creating a Goroutine


 package main

 func main () {
   a=1		                 
   foo()	                 
   a=2
 }

 func foo() {
     // does something ... 
 }
 		                

 package main

 func main () {
    a=1		                 
 go foo()	                 
    a=2
 }

 func foo() {
     // does something ... 
 }
 		  

Exiting a Goroutine

Early Exit

func main() {
	go fmt.Printf("New routine")
	fmt.Printf("Main routine")
}

Delayed Exit

func main() {
	go fmt.Printf("New routine")
	time.Sleep(100 * time.Milisecond)
	fmt.Printf("Main routine")
}

Timing with Goroutines

Synchronization

Example

Task 1 Task 2
x=1  
x=x+1  
GB if GB print x

Threads in Go

Threads in Go are generally handled using wait groups

Sync WaitGroup

Using WaitGroup

WaitGroups

Example


func foo(wg *sync.WaitGroup) {
	fmt.Printf("New routine")
	wg.Done()
}

func main() {
	var wg sync.WaitGroup 
	wg.Add(1)
	go foo(&wg)
	wg.Wait()
	fmt.Printf("Main Routine")
}

Goroutine Communication

Channels

Example


func prod(v1 int, v2 int, c chan int) {
	c <- v1*v2
}

func main() {
	c:=make(chan int)
	go prod(1,2,c)
	go prod(3,4,c)
	a:= <-c
	b:= <-c 
	fmt.Println(a*b)
}


Unbuffered Channel

Block Channel

Blocking and Synchronization

Buffered Channel

Channel Capacity

Channel Blocking, Receive

Chan cap

Channel Blocking, Send

Chan Block Send

Use of Buffering

Buffering in channel

Adding a channel to our goroutine

Note that in this section notes are taken from: https://www.sohamkamani.com/blog/2017/08/24/golang-channels-explained

Directionality

out chan <- int  `
out <- chan int
out :=make(chan int)

After this section, notes are taken from: https://go101.org/article/channel.html if you prefer to have deep dive into channels, you may visit there.

Buffering in channel

These circumstances are called data races. One of the duties in concurrent programming is to control resource sharing among concurrent applications, so that data races will NOT happen. The ways to achieve this duty are called concurrency synchronization, or data synchronization. GO supports several data synchronization techniques. The following section will introduce one of them, channel.

Other duties in concurrent programming include:

Most operations in Go are not synchronized. In other words, they are not concurrency-safe. These operations include value assignments, argument passing and container element manipulations. There are only a few operations which are synchronized, including the several to be introduced channel operations below.

DO NOT COMMUNICATE BY SHARING MEMORY, SHARE MEMORY BY COMMUNICATING *(THROUGH CHANNELS)

Channel Types and Values

Like array, slice and map, each channel type has an element type. A channel can only transfer values of the element type of (the type of) the channel.

Channel types can be bidirectional or single-directional. Assume T is an arbitrary type,

T is called element types of these channel types.

Values of bidirectional channel type chan T can be implicitly converted to both send-only type chan <-T and receive-only type <-chan T , but not vice versa (even if explicitly). Values of send only type chan<-T cannot be converted to receive only type <-chan T.

Each channel has capacity. A channel value with a zero capacity is called unbuffered channel and a channel value with a non-zero capacity is called buffered channel.

For more detailed explanation on channels you can visit https://go101.org/article/channel.html

Take care ! 👋🏻

Maybe next time, topics could be revisited by examples 😉

Ahmet Turkmen

Ahmet Turkmen

Software Engineer

comments powered by Disqus
rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium cool-kubernetes stackoverflow reddit quora quora dev