Created
May 20, 2021 08:07
-
-
Save mugli/e2670015363eb7bca5ee4894f6c3242a to your computer and use it in GitHub Desktop.
Concurrency in Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
A data race happens when processes have to access the same variable concur | |
rently i.e. one process reads from a memory location while another simultaneously | |
writes to the exact same memory location. | |
*/ | |
func main() { | |
number := 0; | |
go func(){ | |
number++ //reading and modifying the value of 'number' | |
}() | |
fmt.Println(number) //reading the value of 'number' | |
} | |
// We can avoid data races by using channels or locks. | |
// They will allow us to synchronize memory access to all shared mutable data |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fan-In: join data from multiple inputs into a single entity. | |
func fanIn(mychannel1, mychannel2 <-chan string) <-chan string { | |
outChannel := make(chan string) | |
var wg sync.WaitGroup | |
wg.Add(2) | |
go func() { | |
for s := range mychannel1 { | |
outChannel <- s | |
} | |
wg.Done() | |
}() | |
go func() { | |
for s := range mychannel2 { | |
outChannel <- s | |
} | |
wg.Done() | |
}() | |
go func() { | |
wg.Wait() | |
// Closing outChannel will help the consumer to range over it | |
close(outChannel) | |
}() | |
return outChannel | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fan-Out: to divide the data from a single source into multiple smaller chunks. | |
func process(s string) { | |
// process | |
} | |
func main() { | |
v := []string{"a", "b", "c"} | |
for _, s := range v { | |
go process(s) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func foo() <-chan string { | |
mychannel := make(chan string) | |
go func() { | |
for i := 0; ; i++ { | |
mychannel <- fmt.Sprintf("%s %d", "Counter at : ", i) | |
} | |
close(mychannel) | |
}() | |
return mychannel // returns the channel as returning argument | |
} | |
func main() { | |
mychannel := foo() // foo() returns a channel. | |
for i := range mychannel { | |
fmt.Printf("%d\n", i) | |
} | |
fmt.Println("Done with Counter") | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
The rules: | |
There are three rounds. Two partners. | |
In each round, both partners will have to process data. | |
A partner cannot move on to the next round until their partner is done with processing. | |
*/ | |
type Data struct { | |
processorName string | |
waitForPartner chan bool | |
} | |
func process(processorName string) <-chan Data { | |
dataChannel := make(chan Data) | |
waitForPartner := make(chan bool) | |
go func() { | |
for i := 0; ; i++ { | |
dataChannel<- Data{ processorName, waitForPartner } | |
// Process takes random time | |
time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond) | |
<-waitForPartner | |
} | |
}() | |
return dataChannel | |
} | |
func fanIn(inChannel1, inChannel2 <-chan Data) <-chan Data { | |
outChannel := make(chan Data) | |
go func() { | |
for { | |
outChannel <- <-inChannel1 | |
} | |
}() | |
go func() { | |
for { | |
outChannel <- <-inChannel2 | |
} | |
}() | |
return outChannel | |
} | |
func main() { | |
processedChannel := fanIn(process("Processor 1"), process("Processor 2")) | |
for round := 0; round < 3; round++ { | |
data1 := <-processedChannel | |
fmt.Println(data1) | |
data2 := <-processedChannel | |
fmt.Println(data1) | |
data1.waitForPartner <- true | |
data2.waitForPartner <- true | |
fmt.Printf("Done with round %d\n", round+1) | |
} | |
fmt.Println("Done with the processing") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment