Estoy desarrollando un servidor HTTP usando boost asio. Hasta ahora, he estado usando operaciones asíncronas (aync_read, async_write etc.), pero quiero hacer que mi servidor sea concurrente, es decir, lo mismo que un servidor que crea un nuevo hilo por cada nuevo Cliente conectado.

He leído algunos foros, etc. y, aparentemente, solo se puede crear un servidor concurrente utilizando las operaciones asincrónicas mencionadas. No entiendo cómo es esto posible.

Quiero decir, teniendo en cuenta que los manejadores de las operaciones asíncronas se ejecutan en el hilo que llamó a io_service.run(), tomemos en cuenta que se está respondiendo a un cliente en este momento. ¿Cómo puede otro cliente hacer una petición y recibir una respuesta mientras el hilo principal está ocupado con el primer cliente?

2
Dan 21 jun. 2017 a las 18:10

3 respuestas

La mejor respuesta

El significado de la palabra "concurrente" es ambiguo.

Tienes razón, un servidor asincrónico no es concurrente en absoluto. Solo puede procesar una solicitud a la vez. Pero la idea clave es que lo que hacen la mayoría de los servidores es en realidad tomar una solicitud, realizar un procesamiento ligero (análisis, serialización, validación, alguna lógica comercial ligera, etc.) y luego llamar a recursos externos (por ejemplo, alguna base de datos). El servidor puede procesar otras solicitudes mientras espera el recurso externo. Entonces, es solo una ilusión de ser concurrente (el procesamiento ocurre uno tras otro pero muy rápido). Y funciona siempre que el procesamiento sea relativamente rápido en comparación con io.

Si se supone que su servidor debe hacer algunos cálculos de CPU duros, obviamente no habrá concurrencia en absoluto. En ese caso, la única forma de hacerlo concurrente es agregar hilos o procesos (posiblemente en múltiples máquinas).

4
freakish 21 jun. 2017 a las 15:31

No estoy seguro si solo está buscando una respuesta teórica o un ejemplo de diseño, pero ¿ha visto el HTTP Server 3 ejemplo para boost.asio?

La concurrencia se logra al tener un pequeño grupo de subprocesos para ejecutar el trabajo. Cuando se deben manejar las devoluciones de llamada, se pueden elegir todos los hilos que llamen io_service.run() para ejecutar la tarea.

0
user3910497 21 jun. 2017 a las 20:42

La E / S asíncrona no hace que el servidor sea concurrente.

De hecho, Asynchronous IO no significa "multiproceso" o "multiprocesamiento" en absoluto. Los servidores Node.js son monohilos y utilizan E / S asíncronas.

IO asíncrono solo significa que su hilo no espera a que termine el IO, sino que también hace otras cosas (como aceptar y procesar nuevas solicitudes entrantes).

Entonces, no, la premisa de que Asynchronous IO hace que el servidor sea concurrente es incorrecta. no lo hace concurrente, lo hace escalable , ya que el subproceso por solicitud no es tan escalable, pero sí lo es un grupo de subprocesos + cola de eventos / corutinas adecuadas. los subprocesos solo se ocupan de las tareas vinculadas a la CPU y la cola de eventos / corutinas administra las operaciones de E / S iniciadas / finalizadas.

1
David Haim 21 jun. 2017 a las 15:34