Introdução à simultaneidade em Go

Introdução à simultaneidade em Go
Leitores como você ajudam a apoiar o MUO. Quando você faz uma compra usando links em nosso site, podemos ganhar uma comissão de afiliado. Consulte Mais informação.

A simultaneidade é um aspecto crucial do desenvolvimento de software moderno, pois permite que os programas lide com eficiência com várias tarefas simultaneamente. Você pode escrever programas que executam várias operações levando a melhor desempenho, capacidade de resposta e utilização de recursos.





Vídeo MUO do dia ROLE PARA CONTINUAR COM O CONTEÚDO

A simultaneidade é um dos recursos responsáveis ​​pela rápida adoção do Go. O suporte integrado do Go para programação simultânea é considerado direto, ajudando a evitar armadilhas comuns, como condições de corrida e impasses.





melhores filmes para adormecer

Simultaneidade em Go

O Go fornece suporte robusto para simultaneidade por meio de vários mecanismos, todos disponíveis em sua biblioteca e cadeia de ferramentas padrão. ir programas obter simultaneidade por meio de goroutines e canais.





As goroutines são funções leves e de execução independente que são executadas simultaneamente com outras goroutines no mesmo espaço de endereço. As goroutines permitem que várias tarefas progridam simultaneamente sem gerenciamento explícito de encadeamentos. As goroutines são mais leves que os threads do sistema operacional e o Go pode executar com eficiência milhares ou até milhões de goroutines simultaneamente.

Canais são o mecanismo de comunicação para coordenação e compartilhamento de dados entre goroutines. Um canal é um conduíte tipado que permite que goroutines enviem e recebam valores. Os canais fornecem sincronização para garantir o compartilhamento seguro de dados entre goroutines, evitando condições de corrida e outros problemas comuns de simultaneidade.



Ao combinar goroutines e canais, o Go fornece um modelo de simultaneidade poderoso e direto que simplifica o desenvolvimento de programas simultâneos, mantendo a segurança e a eficiência. Esses mecanismos permitem que você use facilmente processadores multicore e crie aplicativos altamente escaláveis ​​e responsivos.

Como usar goroutines para execução de código concorrente

O tempo de execução Go gerencia goroutines. As goroutines têm sua pilha, permitindo que tenham uma pegada leve com um tamanho de pilha inicial de alguns kilobytes.





As goroutines são multiplexadas em vários threads do sistema operacional pelo tempo de execução do Go. O agendador de tempo de execução do Go os agenda em threads disponíveis, distribuindo a carga de trabalho com eficiência, permitindo a execução simultânea de várias goroutines em menos threads do sistema operacional.

Criar goroutines é simples. Você usará o ir palavra-chave seguida por uma chamada de função para declarar goroutines.





 func main() { 
    go function1() // Create and execute goroutine for function1
    go function2() // Create and execute goroutine for function2

    // ...
}

func function1() {
    // Code for function1
}

func function2() {
    // Code for function2
}

Quando o programa invoca função1() e função2() com o ir palavra-chave, o tempo de execução do Go executa as funções simultaneamente como goroutines.

Aqui está um exemplo de uso de uma goroutine que imprime texto no console:

 package main 

import (
    "fmt"
    "time"
)

func printText() {
    for i := 1; i <= 5; i++ {
        fmt.Println("Printing text", i)
        time.Sleep(1 * time.Second)
    }
}

func main() {
    go printText() // Start a goroutine to execute the printText function concurrently

    // Perform other tasks in the main goroutine
    for i := 1; i <= 5; i++ {
        fmt.Println("Performing other tasks", i)
        time.Sleep(500 * time.Millisecond)
    }

    // Wait for the goroutine to finish
    time.Sleep(6 * time.Second)
}

O printText função imprime repetidamente algum texto no console com um para loop que é executado cinco vezes após um atraso de um segundo entre cada instrução com o pacote de tempo .

O principal função inicia uma goroutine chamando ir imprimirTexto , que lança o printText funcionar como uma goroutine simultânea separada que permite que a função seja executada simultaneamente com o restante do código no principal função.

Finalmente, para garantir que o programa não saia antes do printText acabamentos goroutine, o hora de dormir A função pausa a goroutine principal por seis segundos. Em cenários do mundo real, você usaria mecanismos de sincronização como canais ou grupos de espera para coordenar a execução de goroutines.

  resultado da impressão de texto com Goroutines

Usando Canais para Comunicação e Sincronização

As goroutines têm suporte integrado para comunicação e sincronização por meio de canais, tornando a escrita de código concorrente mais fácil do que as threads tradicionais, que geralmente requerem mecanismos de sincronização manual, como bloqueios e semáforos.

Você pode pensar em canais como pipelines para fluxo de dados entre goroutines. Uma goroutine pode enviar um valor para o canal e outra goroutine pode receber esse valor do canal. Esse mecanismo garante que a troca de dados seja segura e sincronizada.

Você usará o <- operadora para enviar e receber dados através de canais.

como selecionar uma cor no photoshop

Aqui está um exemplo demonstrando o uso básico de canais para comunicação entre duas goroutines:

 func main() { 
    // Create an unbuffered channel of type string
    ch := make(chan string)

    // Goroutine 1: Sends a message into the channel
    go func() {
        ch <- "Hello, Channel!"
    }()

    // Goroutine 2: Receives the message from the channel
    msg := <-ch
    fmt.Println(msg) // Output: Hello, Channel!
}

O canal no principal função é um canal sem buffer chamado CH criado com o fazer() função. A primeira goroutine envia a mensagem 'Hello, Channel!' no canal usando o <- operador, e a segunda goroutine recebe a mensagem do canal usando o mesmo operador. finalmente, o principal A função imprime a mensagem recebida no console.

  resultado da mensagem de impressão passada via canal

Você pode definir canais digitados. Você especificará o tipo de canal na criação. Aqui está um exemplo que demonstra o uso de diferentes tipos de canais:

 func main() { 
    // Unbuffered channel
    ch1 := make(chan int)

    // Buffered channel with a capacity of 3
    ch2 := make(chan string, 3)

    // Sending and receiving values from channels
    ch1 <- 42 // Send a value into ch1
    value1 := <-ch1 // Receive a value from ch1

    ch2 <- "Hello" // Send a value into ch2
    value2 := <-ch2 // Receive a value from ch2
}

O principal função cria dois canais: ch1 é um canal inteiro sem buffer, enquanto ch2 é um canal de string em buffer com uma capacidade de 3. Você pode enviar e receber valores de e para esses canais usando o <- operador (os valores devem ser do tipo especificado).

Você pode usar canais como mecanismos de sincronização para coordenar a execução de goroutine, aproveitando a natureza de bloqueio das operações de canal.

 func main() { 
    ch := make(chan bool)

    go func() {
        fmt.Println("Goroutine 1")
        ch <- true // Signal completion
    }()

    go func() {
        <-ch // Wait for the completion signal from Goroutine 1
        fmt.Println("Goroutine 2")
    }()

    <-ch // Wait for completion signal from Goroutine 2
    fmt.Println("Main goroutine")
}

O CH canal é booleano. Duas goroutines rodam simultaneamente no principal função. Goroutine 1 sinaliza sua conclusão enviando um verdadeiro valor no canal CH . Goroutine 2 espera pelo sinal de conclusão recebendo um valor do canal. Finalmente, a goroutine principal espera pelo sinal de conclusão da goroutine dois.

Você pode criar aplicativos da Web no Go With Gin

Você pode criar aplicativos da Web de alto desempenho no Go with Gin enquanto aproveita os recursos de simultaneidade do Go.

Você pode usar o Gin para lidar com roteamento HTTP e middleware com eficiência. Aproveite o suporte de simultaneidade integrado do Go empregando goroutines e canais para tarefas como consultas de banco de dados, chamadas de API ou outras operações de bloqueio.