Skip to content

Commit

Permalink
Merge pull request #55 from fabianoflorentino/5-terminar-o-curso
Browse files Browse the repository at this point in the history
Chapter 21: Channels
  • Loading branch information
fabianoflorentino authored Dec 10, 2024
2 parents 8594f30 + d522693 commit 785f4bc
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 1 deletion.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,8 @@ Capítulo 21: Canais
--select Select
--a-expressao-comma-ok A expressão comma ok
--convergencia Convergência
--convergencia --example Convergência - Exemplo
--convergencia --chan-string --example Convergência de Strings - Exemplo
--divergencia Divergência
--context Context

Expand Down Expand Up @@ -475,7 +477,6 @@ Capítulo 21: Exercícios Ninja Nível 10
│   └── questionarie.md
├── go.mod
├── go.sum
├── help.out
├── internal
│   ├── agrupamento_de_dados
│   │   ├── overview.yml
Expand All @@ -485,6 +486,7 @@ Capítulo 21: Exercícios Ninja Nível 10
│   │   ├── overview.yml
│   │   └── topics.go
│   ├── canais
│   │   ├── examples.go
│   │   ├── overview.yml
│   │   └── topics.go
│   ├── concorrencia
Expand Down
135 changes: 135 additions & 0 deletions internal/canais/examples.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Package canais provides examples of using Go channels to synchronize and
// communicate between goroutines. It includes functions to demonstrate
// sending and receiving values through channels, as well as converging
// multiple channels into a single channel for processing.
package canais

import (
"fmt"
"sync"
"time"
)

// wg is a WaitGroup used to wait for a collection of goroutines to finish executing.
// It provides a way to synchronize the completion of multiple goroutines by using
// Add, Done, and Wait methods. The Add method increments the counter by the number
// of goroutines to wait for, the Done method decrements the counter when a goroutine
// completes, and the Wait method blocks until the counter becomes zero.
var wg sync.WaitGroup

// UsingConverge demonstrates the use of channels to converge values from two separate channels (odd and even) into a single channel (converge).
// It starts two goroutines: one to send values to the odd and even channels, and another to receive values from these channels and send them to the converge channel.
// The function then iterates over the values received from the converge channel, printing each value as either "Even Value" or "Odd Value".
// If the value is divisible by 5, a newline is added after the value for better readability.
func UsingConverge() {
odd := make(chan int)
even := make(chan int)
converge := make(chan int)

go sentToConverge(odd, even)
go receiveToConverge(odd, even, converge)

for value := range converge {

if value%2 == 0 {
fmt.Printf("Even Value: %v ", value)
} else {

fmt.Printf("Odd Value: %v ", value)
}
}
}

// UsingConvergeString demonstrates how to converge two string channels into a single channel.
// It creates two channels, chan1 and chan2, by calling workWithChanString with "A" and "B" respectively.
// These channels are then passed to receiveChanStringToConverge, which merges them into a new channel, newChan.
// The function iterates over newChan, printing each value received from the merged channels.
func UsingConvergeString() {
chan1 := workWithChanString("A")
chan2 := workWithChanString("B")

newChan := receiveChanStringToConverge(chan1, chan2)

fmt.Printf("\nUse Ctrl+C to interrupt the program!!\n\n")
for value := range newChan {
fmt.Printf("%v\t", value)
}
}

// sentToConverge sends numbers from 0 to 99 to either the odd or even channel.
// If the number is even, it is sent to the even channel; otherwise, it is sent to the odd channel.
// After sending all numbers, both channels are closed.
func sentToConverge(odd, even chan int) {
for number := 0; number < 100; number++ {
if number%2 == 0 {
even <- number
} else {
odd <- number
}
}
close(odd)
close(even)
}

// receiveToConverge takes three channels as input: odd, even, and converge.
// It starts two goroutines to read values from the odd and even channels and send them to the converge channel.
// The function uses a WaitGroup to ensure both goroutines complete their execution before closing the converge channel.
// This function is useful for merging values from two separate channels into a single channel.
func receiveToConverge(odd, even, converge chan int) {
wg.Add(1)
go func() {
for value := range odd {
converge <- value
}
wg.Done()
}()

wg.Add(1)
go func() {
for value := range even {
converge <- value
}
wg.Done()
}()

wg.Wait()
close(converge)
}

// workWithChanString takes a string value and returns a channel of strings.
// It starts a goroutine that continuously sends formatted strings to the channel.
// Each string is the input value concatenated with an incrementing index, separated by a space.
// The goroutine sleeps for 2 seconds between each send operation.
func workWithChanString(value string) chan string {
stringChan := make(chan string)

go func(value string, chann chan string) {
for idx := 0; ; idx++ {
chann <- fmt.Sprintf("%s %d", value, idx)
time.Sleep(time.Second * 2)
}
}(value, stringChan)

return stringChan
}

// receiveChanStringToConverge converges two input channels (chan1 and chan2) into a single output channel (newChan).
// It launches two goroutines, each of which continuously reads from one of the input channels and sends the received
// value to the output channel. This allows values from both input channels to be received on the single output channel.
// - The line `newChan <- <-chan2` reads a value from chan2 and sends it to newChan.
func receiveChanStringToConverge(chan1, chan2 chan string) chan string {
newChan := make(chan string)

go func() {
for {
newChan <- <-chan1
}
}()
go func() {
for {
newChan <- <-chan2
}
}()

return newChan
}
4 changes: 4 additions & 0 deletions internal/canais/topics.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ func MenuCanais([]string) []format.MenuOptions {
{Options: "--select", ExecFunc: func() { executeSection("Select") }},
{Options: "--a-expressao-comma-ok", ExecFunc: func() { executeSection("A expressão comma ok") }},
{Options: "--convergencia", ExecFunc: func() { executeSection("Convergência") }},
{Options: "--convergencia --example", ExecFunc: func() { UsingConverge() }},
{Options: "--convergencia --chan-string --example", ExecFunc: func() { UsingConvergeString() }},
{Options: "--divergencia", ExecFunc: func() { executeSection("Divergência") }},
{Options: "--context", ExecFunc: func() { executeSection("Context") }},
}
Expand All @@ -73,6 +75,8 @@ func HelpMeCanais() {
{Flag: "--select", Description: "Select"},
{Flag: "--a-expressao-comma-ok", Description: "A expressão comma ok"},
{Flag: "--convergencia", Description: "Convergência"},
{Flag: "--convergencia --example", Description: "Convergência - Exemplo"},
{Flag: "--convergencia --chan-string --example", Description: "Convergência de Strings - Exemplo"},
{Flag: "--divergencia", Description: "Divergência"},
{Flag: "--context", Description: "Context"},
}
Expand Down

0 comments on commit 785f4bc

Please sign in to comment.