# Concurrency & Parallelism

Goroutines are part of making concurrency easy to use.

### Concurrency

Concurrency is the capability to deal with lots of things at once.

concurrency 只能在單一 CPU 核裡執行

### Parallelism

Parallelism is doing lots of things at the same time. It might sound similar to concurrency but its actually different.

Parallelism 可以同時多核處理

### 總結

If the person is doing running on 1 core and tying his laces on another core its Parallelism. If he is running on on 1 core and then switching/stopping to tie his laces on the same core then its concurrent

# Goroutine

Goroutines are functions or methods that run concurrently with other functions or methods.

• go 本身就有數千個 goroutine 在跑
• goroutine 最多運行 GOMAXPROCS 數量(可以設定)
• main() 也是一個 goroutine 稱為 main Goroutine
• Goroutine 可以透過 channel 來進行溝通，防止同時訪問共享的資源，造成競爭

# Channel

Channels can be thought as pipes using which Goroutines communicate. Similar to how water flows from one end to another in a pipe, data can be sent from one end and received from the another end using channels.

• Channel 是 goroutine 之間相互通信的機制（goroutine之間是相互獨立的，因此需要 Channel 來做溝通）
• Channel 中使用的 type 稱之為 element type，比如 int 類型的 channel 寫作為 chan int，無法允許不同 type data 傳輸
• The zero value of a channel is nil，這種 nil chaneel 無法使用，必須向 mapsslices 一樣，使用 ‘make’
• 若沒填寫第二個參數，預設就為 0，則為 unbuffered channel，意思是 sender 和 receiver 必須是同步的才能發送
• make
• Slice: The size specifies the length. The capacity of the slice is equal to its length. A second integer argument may be provided to specify a different capacity; it must be no smaller than the length. For example, make([]int, 0, 10) allocates an underlying array of size 10 and returns a slice of length 0 and capacity 10 that is backed by this underlying array.

• Map: An empty map is allocated with enough space to hold the specified number of elements. The size may be omitted, in which case a small starting size is allocated.

• Channel: The channel’s buffer is initialized with the specified buffer capacity. If zero, or the size is omitted, the channel is unbuffered.

### Sends and receives are blocking by default

• When a data is sent to a channel, the control is blocked in the send statement until some other Goroutine reads from that channel.
• Similarly when data is read from a channel, the read is blocked until some Goroutine writes data to that channel.
• 如果另一方一直對沒有動作，會造成 Deadlock
##### 將上面範例 sleep 改用 channel 改寫

<-done 這行會導致 main goroutine blocked 在這邊，直到其他 goroutine 將 data 寫入 done，不然是不會繼續往下走，也意味著就不需要用 sleep 來停止

• <-done 會等到 channel data 回來才會繼續執行下一行
• <-done 左邊並沒有任何 variable 去接收，因為這邊只是會了要讓他先執行 hello() 並不是要回傳的 value

### Unidirectional channels (單向 channels)

channel 也可以是單向的，only send or receive data

### Closing channels and for range loops on channels

• sender 可以關閉 channel 已告知 receivers，已經沒有 data
• 只有 sender 要關閉 channel，如果沒有 close channel 可能會導致 panic fatal error: all goroutines are asleep - deadlock!
• Channels aren’t like files; you don’t usually need to close them. Closing is only necessary when the receiver must be told there are no more values coming, such as to terminate a range loop.

# Buffered Channels

Provide the buffer length as the second argument to make to initialize a buffered channel:

• 當 buffer 滿了，sends 就會 block 住
• 當 buffer 空了，receives 就會 block 住

### Example2

• ch buffered channel 容量設定 2，當丟給 write 跑 for loop，將 0, 1, 2, 3 丟到 ch 裡面，但因為容量只有 2，所以丟到 1 之後，ch 就會被 block 住，直到 ch 的東西被 reader 取出來，因此一開始顯示兩行就停住
• 因為 reader 在 sleep 後面，所以等兩秒後，main() range 就會開始取出，取出一個就會停兩秒，因此同時間，write() 發現 ch 又有容量，就會繼續塞，因此又滿了
• 接著就會一直重複

# Worker Pool

### WaitGroup

• WaitGroup is a struct type and we are creating a zero value variable
• The way WaitGroup works is by using a counter

what is worker pool?

a worker pool is a collection of threads which are waiting for tasks to be assigned to them. Once they finish the task assigned, they make themselves available again for the next task.

### Example

Core functionalities of our worker pool

• Creation of a pool of Goroutines which listen on an input buffered channel waiting for jobs to be assigned
• Addition of jobs to the input buffered channel
• Writing results to an output buffered channel after job completion
• Read and print results from the output buffered channel

# Select

• The select statement lets a goroutine wait on multiple communication operations.
• A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.
• The syntax is similar to switch except that each of the case statement will be a channel operation
• 當有個任務需要即時的 output，並且有兩台 server 有同樣的 api 可以呼叫，就可以用 select 選擇最快 response 那台來執行

### Default Selection

• The default case in a select is run if no other case is ready.
• 加上 default 就不會有 deadlock 情形發生

# sync.Mutex

Before jumping to mutex, it is important to understand the concept of Critical section in concurrent programming

### Mutex

A Mutex is used to provide a locking mechanism to ensure that only one Goroutine is running the critical section of code at any point of time to prevent race condition from happening.