Go podem em muitas outras linguagens que se basearam em CSP de Tony Hoare. 1. Cada processo é criado para execução sequencial 2. Comunique dados, não compartilhe. Sem compartilhamento de estado. 3. Fácil escalabilidade, adicionando mais do mesmo. (workers) CSP - Conceitos chave
Melvin Conway. Conway sugere que o propósito de uma coroutine é fazer com que um problema seja dividido em partes, ou, sub-tarefas (coroutines) e permitir que as mesmas operam de formas independentes, compartilhando pequenos fragmentos de dados.
nas versões mais novas. Threds do SO geralmente possuem tamanho na stack fixo de 1-2 MB goroutines são gerenciadas pelo Go Runtime, tendo como consequência criação/destrução menos custosas. Threads têm configuração significativa e custo de criação/destrução, já que uma thread precisa solicitar muitos recursos do sistema operacional e retorná-los assim que estiver pronto. goroutines não têm nenhuma identidade, uma consequência de não existir TLS (Thread Local Storage) Threads têm identidade. Elas possuem TID, que identifica cada Thread dentro do processo. goroutines usam canais para se comunicar com outras goroutines com baixa latência Não existe um meio de comunicação fácil entre os threads. Há uma grande latência na comunicação entre threads.
de transferência de dados no qual os dados podem ser passados ou lidos, fazendo com que uma goroutine possa enviar dados para um canal, enquanto outras goroutines possam ler os dados do mesmo canal. “do not communicate by sharing memory; instead, share memory by communicating.”
main() { lambda.Start(processaEventoSQS) } func processaEventoSQS(event events.SQSEvent) error { // cria parametro para definir maximo de workers maxWorkers := len(event.Records) // cria um buffered channel canal := make(chan events.SQSMessage, maxWorkers) // processa as mensagens em Go routines diferentes go processaMensagens(event.Records, canal) // escuta eventos de um canal até que o mesmo esteja fechado for resposta := range canal { fmt.Println(resposta.Body) } return nil } //especifica na sua função que somente canais de envio de mensagem serão aceitos como parâmetro func processaMensagens(mensagens []events.SQSMessage, canal chan<- events.SQSMessage) { for _, mensagem := range mensagens { // realiza processamento e notifica canal canal <- mensagem } // feche o canal close(canal) }
{ lambda.Start(processaEventoSQS) } func processaEventoSQS(event events.SQSEvent) error { // define máximo de goroutines maxBuffer := len(event.Records) // cria um buffered channel canal := make(chan events.SQSMessage, maxBuffer) // processa as mensagens em Go routines diferentes go processaMensagens(event.Records, canal) // escuta eventos de um canal até que o mesmo esteja fechado for resposta := range canal { fmt.Println(resposta.Body) } return nil } package main import ( "fmt" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" ) func main() { lambda.Start(processaEventoSQS) } func processaEventoSQS(event events.SQSEvent) error { // cria canal de consumo canal := make(chan events.SQSMessage) // cria canal para termino do processo quit := make(chan bool) // processa as mensagens em Go routines diferentes go notificaMensagens(event.Records, canal, quit) processMensagens(canal, quit) //finaliza canais close(canal) close(quit) return nil }
canal de consumo canal := make(chan events.SQSMessage) // cria canal para termino do proceso quit := make(chan bool) // processa as mensagens em Go routines diferentes go notificaMensagens(event.Records, canal, quit) processMensagens(canal, quit) //finaliza canais close(canal) close(quit) return nil } func processMensagens(canal chan events.SQSMessage, quit chan bool) { // um loop para processar o recebimento de mensagens for { // select para rotear em que caso deverá ser processado select { case mensagem := <-canal: fmt.Println(mensagem) case <-quit: return } } } //especifica na sua função que somente canais de envio de mensagem serão aceitos como parâmetro func notificaMensagens(mensagens []events.SQSMessage, canal chan<- events.SQSMessage, quit chan bool) { for _, mensagem := range mensagens { canal <- mensagem } quit <- true }
events.SQSMessage) { // um loop para processar o recebimento de mensagens ate o canalEntrada estar fechado for mensagem := range canalEntradaA { // select para rotear em que caso deverá ser processado select { // Envia para o primeiro canal não bloqueado case canalSaida <- mensagem: } } for mensagem := range canalEntradaB { // select para rotear em que caso deverá ser processado select { // Envia para o primeiro canal não bloqueado case canalSaida <- mensagem: } } } Rob Pike - Go Concurrency Patterns
chan events.SQSMessage) { // um loop para processar o recebimento de mensagens ate o canalEntrada estar fechado for mensagem := range canalEntrada { // select para rotear em que caso deverá ser processado select { // Envia para o primeiro canal não bloqueado case canalSaidaA <- mensagem: case canalSaidaB <- mensagem: } } } Go Meetup Smotri+ 23.04.2015
a quantidade de callback a goroutine principal deverá esperar. • Done() sinaliza a conclusão de uma goroutine, decrementando o valor de n especificado no Add(n). • Wait() Gera um lock na goroutine até que todos os callbacks tenham sido enviados através da chamada de Done().
{ lambda.Start(processaEventoSQS) } func processaEventoSQS(event events.SQSEvent) error { // cria canal de consumo canal := make(chan events.SQSMessage) // cria canal para termino do processo quit := make(chan bool) // processa as mensagens em Go routines diferentes go notificaMensagens(event.Records, canal, quit) processMensagens(canal, quit) //finaliza canais close(canal) close(quit) return nil } package main import ( "encoding/json" "fmt" "github.com/aws/aws-lambda-go/events" "github.com/aws/aws-lambda-go/lambda" "sync" ) var wg sync.WaitGroup func main() { lambda.Start(processaEventoSQS) } func processaEventoSQS(event events.SQSEvent) error { // cria canal de consumo canal := make(chan events.SQSMessage) // cria canal para termino do processo quit := make(chan bool) // especifica a quantidade de goroutines a esperar o callback wg.Add(2) // processa as mensagens em Go routines diferentes go notificaMensagens(event.Records, canal, quit, &wg) go processMensagens(canal, quit, &wg) // espera a sincronização dessas goroutines para prosseguir com a conclusão de processamento wg.Wait() //finaliza canais close(canal) close(quit) return nil }