Middle
O que é o tempo de execução (runtime) e como funciona o escalonador (scheduler)?
sobes.tech IA
Resposta da IA
O tempo de execução (runtime) em Go é o ambiente onde os programas Go são executados. Inclui:
- Gestão de memória: O coletor de lixo gerencia automaticamente a alocação e liberação de memória.
- Agendador (scheduler): Gerencia a execução de goroutines em threads do sistema operativo.
- Chamadas ao sistema: Fornece uma interface para interagir com o sistema operativo.
- Primitivas de sincronização: Canais, mutexes e outros mecanismos para coordenar goroutines.
O agendador do Go implementa o modelo M:N (muitas goroutines em muitos threads do sistema operativo). Seus componentes principais:
- G (Goroutine): Um thread leve de execução, basicamente uma abstração sobre uma função.
- M (Machine): Um thread do sistema operativo onde os programas Go são executados.
- P (Processor): Um processador lógico associado a um thread do sistema operativo. Ele mantém uma fila local
runnablede goroutines.
Princípio de funcionamento do agendador:
- As goroutines (G) são criadas e adicionadas a uma fila global ou local
runnable. - Os threads do sistema operativo (M) são associados a processadores lógicos (P). A quantidade de P por padrão é igual ao número de núcleos CPU (
GOMAXPROCS). - P pega uma goroutine da sua fila local. Se a fila local estiver vazia, P tenta "roubar" (steal) goroutines da fila de outro P ou da fila global.
- M executa a goroutine.
- Quando uma goroutine fica bloqueada (por exemplo, ao ler de um canal sem dados ou ao fazer uma chamada ao sistema), M se desassocia de P, e P fica disponível para executar outra goroutine. A goroutine bloqueada é colocada em espera. Quando o bloqueio é removido, a goroutine volta a estar
runnablee é colocada de volta na fila. - Se M fica bloqueado numa chamada ao sistema, ele não mantém P. Um novo M pode ser criado ou um existente pode ser usado para que P possa continuar a executar outras goroutines.
Esta abordagem permite usar eficientemente os recursos do processador e escalar facilmente tarefas paralelas, escondendo a complexidade da gestão de threads do sistema operativo do desenvolvedor.
// Exemplo de criação de uma goroutine
func myFunc() {
// Código da goroutine
}
func main() {
go myFunc() // Início da goroutine
// O programa principal continua a executar em paralelo
}