# Questões de Concorrente ### Questão 01 ###### Fork-sleep-join (3.0) Crie um programa que recebe um número inteiro n como argumento e cria n goroutines. Cada uma dessas goroutines deve dormir por um tempo aleatório de no máximo 5 segundos. A main-goroutine deve esperar todas as goroutines filhas terminarem de executar para em seguida escrever na saída padrão o valor de n. ```go= package main import ( "fmt" "math/rand" "time" ) func printWorking(ch chan int, id int) { randomNumber := rand.Intn(5) fmt.Printf("Goroutine %d sleeping for: %d seconds\n", id, randomNumber) time.Sleep(time.Duration(randomNumber) * time.Second) ch <- randomNumber } func forkSleepJoin(routines int, finishingCh chan int) { channel := make(chan int) for i := 1; i <= routines; i++ { go printWorking(channel, i) } for i := 1; i <= routines; i++ { <-channel } fmt.Println("Number of GoRoutines:", routines) close(finishingCh) } func main() { channel := make(chan int) forkSleepJoin(5, channel) <-channel } ``` ### Questão 02 ###### two-phase sleep (3.0) Crie um programa que recebe um número inteiro n como argumento e cria n goroutines. Cada uma dessas goroutines deve dormir por um tempo aleatório de no máximo 5 segundos. Depois que acordar, cada thread deve sortear um outro número aleatório s (entre 0 e 10). **Somente depois** de todas as n goroutines terminarem suas escolhas (ou seja, ao fim da primeira fase), começamos a segunda fase. Nesta segunda fase, a n-ésima goroutine criada deve dormir pelo tempo s escolhido pela goroutine n - 1 (faça a contagem de maneira modular, ou seja, a primeira goroutine dorme conforme o número sorteado pela última). ```go= package main import ( "fmt" "math/rand" "sync" "time" ) func createChannels(numberChannels int) []chan int { var channels []chan int for i := 0; i < numberChannels; i++ { channel := make(chan int) channels = append(channels, channel) } return channels } var finishingBarrier sync.WaitGroup var barrier sync.WaitGroup func main() { goRoutines := 5 channels := createChannels(goRoutines) barrier.Add(goRoutines) finishingBarrier.Add(goRoutines) for i := 0; i < goRoutines; i++ { modularIndex := (i + 1) % goRoutines go execFunc(channels[i], channels[modularIndex]) } barrier.Wait() fmt.Println("hum..chegou aqui") finishingBarrier.Wait() fmt.Println("Finished!") } func execFunc(inCh chan int, outCh chan int) { firstSleep := rand.Intn(5) time.Sleep(time.Duration(firstSleep) * time.Second) randomNumber := rand.Intn(10) inCh <- randomNumber fmt.Println("Phase one active! RandomNumber:", randomNumber) barrier.Done() barrier.Wait() fmt.Println("Phase two active!") sleepTime := <-outCh time.Sleep(time.Duration(sleepTime) * time.Second) fmt.Println("Phase two active! Sleep time:", sleepTime) finishingBarrier.Done() } ```