Go: Processos e Concorrência
De Aulas
Afluentes: Sistemas Distribuídos e Mobile
Subprocessos
1package main
2
3import (
4 "fmt"
5 "math/rand"
6 "sync"
7 "time"
8)
9
10func child(wg *sync.WaitGroup) {
11 defer wg.Done() // decrementa o contador de processo
12 fmt.Println("Luke: Noooooo.....") // imprime na tela
13 for i := 0; i < 5; i++ { // executa o laço 5 vezes
14 fmt.Println("Luke: No!") // imprime n a tela
15 d := rand.Intn(2000) // retorna um número randômico de 0 a 1999
16 time.Sleep(time.Duration(d) * time.Millisecond) // aguarda um tempo
17 }
18 fmt.Println("Luke Skywalker falls.") // imprime na tela
19}
20
21func main() {
22 var wg sync.WaitGroup // wg é tilizado para sincronizar os processos
23 wg.Add(1) // incrementa o contador de processos
24 go child(&wg) // chama a rotina child paralelamente
25 fmt.Println("Vader: Luke! I am your father...") // imprime na tela
26 for i := 0; i < 5; i++ { // executa o laço 5 vezes
27 fmt.Println("Vader: Yes!") // imprime na tela
28 d := rand.Intn(2000) // retorna um número randômico de 0 a 1999
29 time.Sleep(time.Duration(d) * time.Millisecond) // aguarda um tempo
30 }
31 wg.Wait() // aguarda os subprocessos terminarem
32 fmt.Println("Dart Vader leaves.") // imprime na tela
33}
Comunicação entre Processos
1package main
2
3import (
4 "fmt"
5 "time"
6)
7
8func child(fc chan string, cc chan string) {
9 msg := <-cc // aguarda a mensagem do pai
10 fmt.Println("CHILD: Father says " + msg) // imprime na tela
11 time.Sleep(2 * time.Second) // aguarda 2 segundos
12 fmt.Println("CHILD: I will response just ok") // imprime na tela
13 fc <- "ok!" // envia a resposta pelo canal do pai
14}
15
16func main() {
17 fatherChannel := make(chan string) // canal de comunicação do pai
18 childCHannel := make(chan string) // canal de comunicação do filho
19 go child(fatherChannel, childCHannel) // chama a rotina child paralelamente
20 fmt.Println("FATHER: I will say hello to my child") // imprime na tela
21 msg := "hello" // cria a variável msg e atribui a string hello
22 childCHannel <- msg // envia a mensagem hello pelo canal do filho
23 msg = <-fatherChannel // aguarda a resposta do filho
24 fmt.Println("FATHER: I receive " + msg + " from child") // imprime na tela
25}
Multifilhos
Cria n filhos e aguarda eles terminarem. utiliza o sync.WaitGroup
para sincronizar os processos. Ou seja, o pai irá aguardar todos os filhos terminarem para continuar sua execução.
1package main
2
3import (
4 "fmt"
5 "math/rand"
6 "sync"
7 "time"
8)
9
10func child(wg *sync.WaitGroup, id int) { // função do filho
11 defer wg.Done() // decrementa o sincronizador
12 for i := 0; i < 5; i++ { // conta até 5
13 fmt.Println("CHILD[", id, "] ", i) // imprime i
14 d := rand.Intn(2000) // pega um valor randômico
15 time.Sleep(time.Duration(d) * time.Millisecond) // pausa um tempo aleatório
16 }
17 fmt.Println("CHILD[", id, "] done...") // imprime a finalização
18}
19
20func main() { // programa principal
21 fmt.Println("START PROGRAM...") // imprime na tela
22 var wg sync.WaitGroup // inicializa o sincronizador
23 for i := 0; i < 5; i++ { // cria 5 filhos
24 wg.Add(1) // adiciona um no sincronizador
25 go child(&wg, i) //cria filho
26 }
27 wg.Wait() // aguarda todos os filhos terminarem
28 fmt.Println("END PROGRAM...") // imprime na tela
29}