"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > GO: Simultaneidade vs Paralelismo para Leigos.

GO: Simultaneidade vs Paralelismo para Leigos.

Publicado em 01/09/2024
Navegar:378

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:

GO: Concurrencia vs Paralelismo Para Tontos.

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() {
    ch 



Exemplo 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; i 



A 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 10

embora à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 9

ou 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 10

Por 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 Raudales

X/Twitter
Github

Declaração de lançamento Este artigo está reproduzido em: https://dev.to/lucatonyraudales/go-concurrencia-vs-paralelismo-para-tontos-2fnn?1 Caso haja alguma infração, entre em contato com [email protected] para excluí-la
Tutorial mais recente Mais>

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