Sou apenas um usuário casual do Google Go, portanto, aproveite o seguinte com um pouco de sal.
A Wikipédia define tópicos verdes como "threads agendados por uma máquina virtual (VM) em vez de nativamente pelo subjacente sistema operacional". Os encadeamentos verdes emulam ambientes multithread sem depender de nenhum recurso nativo do SO e são gerenciados no espaço do usuário em vez do espaço do kernel, permitindo que trabalhem em ambientes que não possuem suporte a encadeamentos nativos.
Go (ou mais exatamente as duas implementações existentes) é um idioma que produz somente código nativo - ele não usa uma VM. Além disso, o planejador nas implementações atuais de tempo de execução depende de encadeamentos no nível do SO (mesmo quando GOMAXPROCS = 1). Então eu acho que falar sobre tópicos verdes para o modelo Go é um pouco abusivo.
Pessoas do Google cunharam o termo goroutine especialmente para evitar a confusão com outros mecanismos de concorrência (como corrotinas ou threads ou processos leves).
Naturalmente, o Go suporta um modelo de encadeamento M: N, mas parece muito mais próximo do modelo de processo Erlang do que do modelo de encadeamento verde Java.
Aqui estão alguns benefícios do modelo Go sobre encadeamentos verdes (como implementado no início da JVM):
-
Diversos núcleos ou CPUs podem ser usados de forma eficaz, de forma transparente para o desenvolvedor. Com o Go, o desenvolvedor deve cuidar da simultaneidade. O tempo de execução do Go cuidará do paralelismo. As implementações de encadeamentos verdes Java não foram escalonadas em vários núcleos ou CPUs.
-
Chamadas do sistema e C não bloqueiam o agendador (todas as chamadas do sistema, não apenas as que suportam E / Ss multiplexadas em loops de evento). As implementações de encadeamentos verdes poderiam bloquear todo o processo quando uma chamada ao sistema de bloqueio fosse feita.
-
Copiando ou pilhas segmentadas. Em Go, não há necessidade de fornecer um tamanho máximo de pilha para a goroutine. A pilha cresce de forma incremental, conforme necessário. Uma conseqüência é que uma goroutine não requer muita memória (4KB-8KB), então um grande número delas pode ser gerado com alegria. O uso de Goroutine pode, portanto, ser difundido.
Agora, para abordar as críticas:
-
Com o Go, você não precisa escrever um agendador de espaço de usuário: ele já é fornecido com o tempo de execução. É um software complexo, mas é o problema dos desenvolvedores Go, não dos usuários Go. Seu uso é transparente para os usuários do Go. Entre os desenvolvedores Go, Dmitri Vyukov é um especialista em programação lockfree / waitfree, e ele parece estar especialmente interessado em abordar os eventuais problemas de desempenho do agendador. A implementação atual do planejador não é perfeita, mas vai melhorar.
-
A sincronização traz problema e complexidade de desempenho: isso é parcialmente verdadeiro também com o Go. Mas observe que o modelo Go tenta promover o uso de canais e uma decomposição limpa do programa em goroutines concorrentes para limitar a complexidade da sincronização (ou seja, compartilhar dados por comunicação, em vez de compartilhar a memória para se comunicar). A propósito, a implementação Go de referência fornece várias ferramentas para resolver problemas de desempenho e simultaneidade, como um gerador de perfis , e um detector de corrida .
-
Em relação a falha de página e "falsificação de vários segmentos", observe que o Go pode programar a linha de comando em vários encadeamentos do sistema. Quando um encadeamento é bloqueado por qualquer motivo (falha de página, bloqueio de chamadas do sistema), isso não impede que os outros encadeamentos continuem a programar e executar outras goroutines. Agora, é verdade que uma falha de página bloqueará o encadeamento do SO, com todas as goroutines supostamente agendadas neste encadeamento. No entanto, na prática, a memória heap do Google não deve ser trocada. Isso seria o mesmo em Java: as linguagens coletadas pelo lixo não acomodam muito bem a memória virtual. Se o seu programa deve lidar com falhas de página de uma forma graciosa, se provavelmente porque ele tem que gerenciar alguma memória fora do heap. Nesse caso, encapsular o código correspondente com funções de acesso C simplesmente resolverá o problema (porque, novamente, chamadas C ou bloqueio de chamadas do sistema nunca bloqueiam o agendador de tempo de execução Go).
Portanto, IMO, goroutines não são segmentos verdes, e a linguagem Go e a implementação atual abordam principalmente essas críticas.