Uses the go keyword for the line of code to run concurrently
Go will not wait for the code to finish executing before moving on
Needs to use WaitGroups to ensure that the program does not finish executing before the subtasks has finished
Amount of concurrency/parallelism is limited to the number of cores in our CPU
WaitGroup
import( "sync")var wg = sync.WaitGroupfunc foo() { for i:=0; i < condition; i++ { wg.Add(1) go bar() } wg.Wait()}func bar() { wg.Done()}
Mutex
Since concurrent programming means that if we add results to an array, it may not be in order, we should use mutex to control the data
Mutual exclusion, methods are lock() and unlock()
We can also use a RWMutex{}, which has additional methods RLock() and RUnlock()
import( "sync")var wg = sync.WaitGroupvar m = sycn.Mutex{}var results = []string{}func foo() { for i:=0; i < condition; i++ { wg.Add(1) go bar() } wg.Wait()}func bar() { m.Lock() // checks if a lock has been already set, if yes, then it will wait here until the lock is released before locking and continuing results = append(results, someValue) m.Unlock() wg.Done()}
Channels
Enables GoRoutines to pass around information
Similar to an array, which only has enough room for 1 value
Features
Hold data
Thread safe: avoid data erasure when reading and writing code
Listen for data: can block code until one of these events happen
Making channels
package mainfunc main() { var c = make(chan int) c <- 1 // adds 1 to the channel}
Deadlocks
Happens if we assign a value from a channel to a variable without GoRoutines, because it blocks code and Go is smart enough to realise that it is an error
Using it with GoRoutines
package mainimport "fmt"func main() { var c = make(chan int) go process(c) for i:= range c { // for loops works with channels fmt.Println(i) }}func process(c chan int) { // defer close(c) also works for i := 0; i < 5; i ++ { c <- i } close(c) // prevents deadlock error}
Storing more values in a channel
make(chan int, 5)
This allows the main program to continue running other code, since we have more room in a channel and we do not need to pop values out of the channel before printing