Erlang, Go y Rust afirman de una manera u otra que admiten la programación concurrente con "hilos" / corutinas baratos. Las preguntas frecuentes de Go indican:
Es práctico crear cientos de miles de gorutinas en el mismo espacio de direcciones.
El tutorial de óxido dice:
Debido a que las tareas son significativamente más baratas de crear que los hilos tradicionales, Rust puede crear cientos de miles de tareas concurrentes en un sistema típico de 32 bits.
La documentación de Erlang dice:
El tamaño de almacenamiento dinámico inicial predeterminado de 233 palabras es bastante conservador para admitir sistemas Erlang con cientos de miles o incluso millones de procesos.
Mi pregunta: ¿qué tipo de aplicación requiere tantos hilos concurrentes de ejecución? Solo los servidores web más ocupados reciben incluso miles de visitantes simultáneos. Las aplicaciones de tipo jefe-trabajador / despachador de trabajo que he escrito alcanzan rendimientos decrecientes cuando el número de subprocesos / procesos es mucho mayor que el número de núcleos físicos. Supongo que podría tener sentido para aplicaciones numéricas, pero en realidad la mayoría de la gente delega paralelismo a bibliotecas de terceros escritas en Fortran / C / C ++, no en estos lenguajes de nueva generación.
fuente
Respuestas:
un caso de uso: websockets:
como los websockets son de larga duración en comparación con las solicitudes simples, en un servidor ocupado se acumularán muchos websockets con el tiempo. microthreads le brinda un buen modelado conceptual y también una implementación relativamente fácil.
más en general, los casos en que numerosas unidades más o menos autónomas están esperando que ocurran ciertos eventos deberían ser buenos casos de uso.
fuente
Podría ayudar pensar en lo que Erlang fue diseñado originalmente para hacer, que era administrar las telecomunicaciones. Actividades como enrutamiento, conmutación, recopilación / agregación de sensores, etc.
Llevar esto al mundo web: considere un sistema como Twitter . El sistema probablemente no usaría microthreads en la generación de páginas web, pero podría usarlos en su colección / almacenamiento en caché / distribución de tweets.
Este artículo podría ser de más ayuda.
fuente
En un lenguaje en el que no está permitido modificar variables, el simple acto de mantener el estado requiere un contexto de ejecución separado (que la mayoría de las personas llamaría un hilo y Erlang llama un proceso). Básicamente, todo es un trabajador.
Considere esta función de Erlang, que mantiene un contador:
En un lenguaje OO convencional como C ++ o Java, lo lograrías teniendo una clase con un miembro de clase privada, métodos públicos para obtener o cambiar su estado y un objeto instanciado para cada contador. Erlang reemplaza la noción del objeto instanciado con un proceso, la noción de métodos con mensajes y el mantenimiento del estado con llamadas de cola que reinician la función con cualquier valor que forme el nuevo estado. El beneficio oculto en este modelo, y la mayor parte de la razón de ser de Erlang, es que el lenguaje serializa automáticamente el acceso al valor del contador mediante el uso de una cola de mensajes, lo que hace que el código concurrente sea muy fácil de implementar con un alto grado de seguridad .
Probablemente esté acostumbrado a la idea de que los cambios de contexto son caros, lo que sigue siendo cierto desde la perspectiva del sistema operativo host. El tiempo de ejecución de Erlang es en sí mismo un pequeño sistema operativo sintonizado, por lo que cambiar entre sus propios procesos es rápido y eficiente, todo mientras mantiene el número de cambios de contexto que el sistema operativo hace al mínimo. Por esta razón, tener miles de procesos no es un problema y se recomienda.
fuente
counter/1
debería usar una c minúscula;) Traté de arreglarlo, pero a StackExchange no le gustan las ediciones de 1 carácter.1) El hecho de que un idioma "escale" significa que hay menos posibilidades de que abandones ese idioma cuando las cosas se vuelvan más complejas en el futuro. (Esto se llama el concepto de "Producto completo"). Muchas personas están abandonando Apache para Nginx por esta misma razón. Si estás cerca del "límite duro" impuesto por la sobrecarga del hilo, te asustarás y comenzarás a pensar en formas de superarlo. Los sitios web nunca pueden predecir cuánto tráfico obtendrán, por lo que pasar un poco de tiempo haciendo que las cosas sean escalables es razonable.
2) Una gorutina por solicitud, solo el comienzo. Hay muchas razones para usar gorutinas internamente.
El rendimiento no es la única razón para dividir un programa en CSP . En realidad, puede hacer que el programa sea más fácil de entender, y algunos problemas se pueden resolver con mucho menos código.
Como en las diapositivas vinculadas anteriormente, tener concurrencia en su código es una forma de organizar el problema. No tener gorutinas es como no tener una estructura de datos de Mapa / Dictonario / Hash en su idioma. Puedes sobrevivir sin eso. Pero una vez que lo tiene, comienza a usarlo en todas partes, y realmente simplifica su programa.
En el pasado, esto significaba "rodar su propia" programación multiproceso. Pero esto era complejo y peligroso: todavía no hay muchas herramientas para asegurarte de que no estás creando razas. ¿Y cómo evita que un futuro mantenedor cometa un error? Si observa programas grandes / complejos, verá que gastan MUCHOS recursos en esa dirección.
Dado que la concurrencia no es una parte de primera clase de la mayoría de los idiomas, los programadores de hoy tienen un punto ciego de por qué les sería útil. Esto solo se hará más evidente a medida que cada teléfono y reloj de pulsera se dirija hacia 1000 núcleos. Ve a los barcos con una herramienta de detector de carreras incorporada.
fuente
Para Erlang es común tener un proceso por conexión u otra tarea. Entonces, por ejemplo, un servidor de transmisión de audio puede tener 1 proceso por usuario conectado.
Erlang VM está optimizado para manejar miles o incluso cientos de miles de procesos al hacer que los cambios de contexto sean muy baratos.
fuente
Conveniencia. Cuando comencé a hacer programación de subprocesos múltiples, hacía mucha simulación y desarrollo de juegos para divertirme. Descubrí que es muy conveniente simplemente desenrollar un hilo para cada objeto y dejar que haga lo suyo en lugar de procesar cada uno a través de un bucle. Si su código no se ve afectado por un comportamiento no determinista y no tiene colisiones, puede facilitar la codificación. Con el poder disponible para nosotros ahora, si tuviera que volver a eso, ¡me puedo imaginar fácilmente cortar un par de miles de hilos debido a tener suficiente poder de procesamiento y memoria para manejar tantos objetos discretos!
fuente
Un ejemplo simple para Erlang, que fue diseñado para la comunicación: transferir paquetes de red. Cuando realiza una solicitud http, es posible que tenga miles de paquetes TCP / IP. Agregue a esto que todos se conectan al mismo tiempo, y usted tiene su caso de uso.
Considere muchas aplicaciones utilizadas internamente por cualquier gran empresa para manejar sus pedidos o lo que sea que necesiten. Los servidores web no son lo único que necesita hilos.
fuente
Aquí me vienen a la mente algunas tareas de renderizado. Si está haciendo una larga cadena de operaciones en cada píxel de una imagen, y si esas operaciones son paralelizables, incluso una imagen relativamente pequeña de 1024x768 está en el soporte de "cientos de miles".
fuente