Bem-vindo a esta postagem com um título um tanto degradante.
Mas, neste post quero explicar para vocês quais são essas 2 características da programação de uma forma bem simples, dessa vez usando minha linguagem de programação favorita GOLANG.
Vamos imaginar uma cozinha:
Cozinhar um prato: Isso representa uma tarefa.
Um cozinheiro: Ele é um processador.
Concorrência:
Vários cozinheiros na cozinha: Cada um preparando um prato diferente.
In Go: Todo cozinheiro seria uma goroutine. Embora a cozinha (processador) possua apenas um forno, os cozinheiros podem trabalhar nos pratos simultaneamente, dedicando tempo a outras tarefas enquanto esperam que o forno fique disponível.
Paralelismo:
Vários fornos: Cada cozinheiro tem seu próprio forno.
In Go: Se tivermos vários processadores físicos, cada goroutine poderá rodar em um processador diferente, cozinhando vários pratos ao mesmo tempo na vida real.
Qual é a diferença?
Concorrência: As tarefas são executadas entrelaçadas, dando a ilusão de paralelismo, mesmo em um único processador.
Paralelismo: As tarefas são executadas simultaneamente em vários processadores, o que acelera significativamente o processo.
Como usá-los no Go?
Goroutines: São como fios leves. Para criar uma goroutine, simplesmente usamos a palavra-chave go antes de uma função:
Vamos ver um exemplo de como podemos usar goroutines em golang:
go func() { // Código que se ejecutará en una goroutine }()
Canais: são canais através dos quais goroutines podem se comunicar e sincronizar.
Imagine que são tubos para passar ingredientes entre os cozinheiros
ch := make(chan int) go func() { chExemplo prático:
package main import ( "fmt" "time" ) func worker(id int, c chan int) { for n := range c { fmt.Printf("Worker %d received %d\n", id, n) time.Sleep(time.Second) } } func main() { c := make(chan int) for i := 1; iA saída deste código seria
Worker 1 received 1 Worker 2 received 2 Worker 3 received 3 Worker 4 received 4 Worker 5 received 5 Worker 1 received 6 Worker 2 received 7 Worker 3 received 8 Worker 4 received 9 Worker 5 received 10embora às vezes possa parecer assim
Worker 5 received 1 Worker 1 received 3 Worker 2 received 2 Worker 4 received 5 Worker 3 received 4 Worker 3 received 6 Worker 5 received 10 Worker 2 received 8 Worker 4 received 7 Worker 1 received 9ou assim
Worker 5 received 1 Worker 1 received 2 Worker 2 received 3 Worker 3 received 4 Worker 4 received 5 Worker 1 received 6 Worker 2 received 7 Worker 3 received 8 Worker 5 received 9 Worker 4 received 10Por que a saída muda toda vez que executo o programa?
A principal razão pela qual a saída do programa muda a cada execução é devido à natureza não determinística da simultaneidade.
Aqui está um resumo do que está acontecendo:
Crie um canal: make(chan int) cria um canal de números inteiros. Este canal será utilizado para comunicação entre goroutines.
Iniciar goroutines: O loop para i := 1; eu A função de trabalho recebe o ID e o canal.
Enviar valores para o canal: O loop para n := 1; n 1 a 10 para o canal.
Fechar o canal: A chamada close(c) fecha o canal, indicando que nenhum outro valor será enviado.
Receber valores do canal: Cada goroutine recebe valores do canal usando o loop for n := range c. Quando um valor é recebido, ele é impresso no console.
Aguarde a conclusão das goroutines: A chamada time.Sleep(time.Second) garante que a goroutine principal aguarde a conclusão das outras goroutines antes de sair.
Até agora:
Criamos 5 goroutines (cozinheiros) que recebem números através de um canal.
Enviamos números ao canal para os cozinheiros processarem.
Os cozinheiros trabalham simultaneamente, processando os números à medida que os recebem.Por que usar simultaneidade e paralelismo em Go?
Melhor desempenho: especialmente em tarefas vinculadas a E/S (como ler arquivos ou fazer solicitações HTTP).
Maior capacidade de resposta: o aplicativo pode continuar respondendo a outras solicitações enquanto uma tarefa está bloqueada.
Arquiteturas mais escaláveis: você pode distribuir o trabalho em vários núcleos ou máquinas.Lembrar!
A simultaneidade e o paralelismo são ferramentas poderosas, mas também podem tornar o código mais complexo de entender e depurar. É importante usá-los com cuidado e compreender suas implicações.
Quer se aprofundar em um tópico específico?
Podemos explorar conceitos como:
Sincronização: Mutexes, grupos de trabalho, etc.
Padrões de simultaneidade: produtor-consumidor, pipeline, etc.
Teste simultâneo: como testar código simultâneo de maneira eficaz.Saudações,
Lucatonny RaudalesX/Twitter
Github
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3