O Go pode gerar e se comunicar com processos externos sem iniciar um thread do SO por processo externo?
Versão curta:
É possível no Golang gerar vários processos externos (comandos do shell)em paralelo, de modo que não inicie umsegmento do sistema operacional por processo externo ... e ainda conseguir receber sua saída quando terminar?
Versão mais longa:
No Elixir, se você usar portas, poderá gerar milhares de processos externos sem realmente aumentar o número de threads na máquina virtual Erlang.
Por exemplo. o seguinte snippet de código, que inicia 2500 externossleep
processos, é gerenciado por apenas 20threads do sistema operacional sob a VM Erlang:
defmodule Exmultiproc do
for _ <- 1..2500 do
cmd = "sleep 3600"
IO.puts "Starting another process ..."
Port.open({:spawn, cmd}, [:exit_status, :stderr_to_stdout])
end
System.cmd("sleep", ["3600"])
end
(Desde que você definaulimit -n
para um número alto, como 10000)
Por outro lado, o código a seguir no Go, que deve fazer a mesma coisa - iniciando 2500 externossleep
processos - também inicia 2500threads do sistema operacional. Então, obviamente, começa umsegmento do sistema operacional por chamada do sistema (bloqueando?) (para não bloquear a CPU inteira ou similar, se bem entendi):
package main
import (
"fmt"
"os/exec"
"sync"
)
func main() {
wg := new(sync.WaitGroup)
for i := 0; i < 2500; i++ {
wg.Add(1)
go func(i int) {
fmt.Println("Starting sleep ", i, "...")
cmd := exec.Command("sleep", "3600")
_, err := cmd.Output()
if err != nil {
panic(err)
}
fmt.Println("Finishing sleep ", i, "...")
wg.Done()
}(i)
}
fmt.Println("Waiting for WaitGroup ...")
wg.Wait()
fmt.Println("WaitGroup finished!")
}
Assim, eu queria saber se existe uma maneira de escrever o código Go para que ele faça o mesmo que o código Elixir, não abrindo umsegmento do sistema operacional por processo externo?
Estou basicamente procurando uma maneira de gerenciar pelo menos alguns milhares de processos externos de longa execução (até 10 dias), de uma maneira que cause o mínimo de problemas possível com quaisquer limites físicos ou virtuais no sistema operacional.
(Desculpe por qualquer erro nos códigos, pois sou novo no Elixir e, e bastante novo no Go. Estou ansioso para conhecer qualquer erro que esteja cometendo.)
EDIT: Esclarecido sobre o requisito para executar os processos de longa execução em paralelo.