Solo soy un usuario casual de Go, así que tome lo siguiente con un grano de sal.
Wikipedia define hilos verdes como "hilos programados por una máquina virtual (VM) en lugar de ser nativos por el sistema operativo subyacente". Los subprocesos verdes emulan entornos multiproceso sin depender de las capacidades nativas del sistema operativo, y se administran en el espacio del usuario en lugar del espacio del kernel, lo que les permite trabajar en entornos que no tienen soporte de subprocesos nativos.
Go (o más exactamente las dos implementaciones existentes) es un lenguaje que solo produce código nativo, no utiliza una VM. Además, el planificador en las implementaciones de tiempo de ejecución actuales se basa en subprocesos a nivel del sistema operativo (incluso cuando GOMAXPROCS = 1). Así que creo que hablar de hilos verdes para el modelo Go es un poco abusivo.
Ir a la gente ha acuñado el término gorutina especialmente para evitar la confusión con otros mecanismos de concurrencia (como las rutinas o hilos o procesos ligeros).
Por supuesto, Go admite un modelo de subprocesos M: N, pero se parece mucho más al modelo de proceso Erlang que al modelo de subproceso verde Java.
Aquí hay algunos beneficios del modelo Go sobre hilos verdes (como se implementó en la primera JVM):
Se pueden usar múltiples núcleos o CPU de manera efectiva, de manera transparente para el desarrollador. Con Go, el desarrollador debe ocuparse de la concurrencia. El tiempo de ejecución de Go se encargará del paralelismo. Las implementaciones de hilos verdes de Java no se escalaron en múltiples núcleos o CPU.
El sistema y las llamadas C no bloquean el programador (todas las llamadas al sistema, no solo las que admiten E / S multiplexadas en bucles de eventos). Las implementaciones de subprocesos verdes podrían bloquear todo el proceso cuando se realizó una llamada al sistema de bloqueo.
Copias o pilas segmentadas. En Go, no es necesario proporcionar un tamaño de pila máximo para la goroutine. La pila crece de forma incremental según sea necesario. Una consecuencia es que una rutina no requiere mucha memoria (4KB-8KB), por lo que una gran cantidad de ellas puede generarse felizmente. El uso de goroutina puede por lo tanto ser generalizado.
Ahora, para abordar las críticas:
Con Go, no tiene que escribir un planificador de espacio de usuario: ya se proporciona con el tiempo de ejecución. Es un software complejo, pero es el problema de los desarrolladores de Go, no de los usuarios de Go. Su uso es transparente para los usuarios de Go. Entre los desarrolladores de Go, Dmitri Vyukov es un experto en programación sin bloqueo / sin espera, y parece estar especialmente interesado en abordar los posibles problemas de rendimiento del programador. La implementación actual del planificador no es perfecta, pero mejorará.
La sincronización trae problemas de rendimiento y complejidad: esto también es parcialmente cierto con Go. Pero tenga en cuenta que el modelo Go intenta promover el uso de canales y una descomposición limpia del programa en goroutines concurrentes para limitar la complejidad de la sincronización (es decir, compartir datos mediante la comunicación, en lugar de compartir la memoria para comunicarse). Por cierto, la implementación Go de referencia proporciona una serie de herramientas para abordar problemas de rendimiento y concurrencia, como un generador de perfiles y un detector de carrera .
Con respecto a la falla de la página y la "falsificación de múltiples hilos", tenga en cuenta que Go puede programar goroutine en múltiples hilos del sistema. Cuando un hilo se bloquea por cualquier motivo (error de página, bloqueo de llamadas del sistema), no impide que los otros hilos continúen programando y ejecutando otras rutinas. Ahora, es cierto que un error de página bloqueará el hilo del sistema operativo, con todas las rutinas supuestamente programadas en este hilo. Sin embargo, en la práctica, no se supone que la memoria de almacenamiento dinámico Go se intercambie. Esto sería lo mismo en Java: los lenguajes recolectados de basura no se adaptan muy bien a la memoria virtual de todos modos. Si su programa debe manejar la falla de la página de una manera elegante, probablemente porque tiene que administrar algo de memoria fuera del montón. En ese caso,
Entonces, en mi opinión, las gorutinas no son hilos verdes, y el lenguaje Go y la implementación actual abordan principalmente estas críticas.