c++ - que - select en c
¿Por qué debería usar sockets que no bloquean o bloquean? (2)
Al principio, debo preguntar cuál es el mejor en qué estados? Por ejemplo, un servidor MMORPG en tiempo real. ¿Qué sucede si creo un hilo por cliente en lugar de usar sockets que no son de bloqueo? O ¿Qué pasa si uso un hilo que contiene todos los sockets no bloqueantes? ¿Puedes explicarme las ventajas?
Continuaré diciendo que para casi cualquier cosa, excepto los programas de juguete, debe usar enchufes que no sean de bloqueo como una cuestión de rutina.
Bloquear los sockets causa un problema grave: si la máquina en el otro extremo (o cualquier parte de su conexión) falla durante una llamada de bloqueo, su código terminará bloqueado hasta que se agote el tiempo de espera de la pila IP. En un caso típico, eso es alrededor de 2 minutos, lo cual es completamente inaceptable para la mayoría de los propósitos. La única forma 1 de abortar esa llamada de bloqueo es terminar el hilo que lo creó, pero terminar un hilo casi siempre es inaceptable, ya que es esencialmente imposible limpiarlo y reclamar los recursos que haya asignado. Los sockets no bloqueantes hacen que sea trivial abortar una llamada cuando / si es necesario, sin hacer nada con el hilo que realizó la llamada.
Es posible hacer que los sockets de bloqueo funcionen bien si se usa un modelo de procesos múltiples. Aquí, simplemente genera un proceso completamente nuevo para cada conexión. Ese proceso usa un socket de bloqueo, y cuando / si algo sale mal, simplemente matas todo el proceso. El sistema operativo sabe cómo limpiar los recursos de un proceso, por lo que la limpieza no es un problema. Sin embargo, todavía tiene otros problemas potenciales: 1) es muy necesario un monitor de proceso para matar procesos cuando sea necesario, y 2) generar un proceso suele ser un poco más caro que crear un socket. No obstante, esta puede ser una opción viable, especialmente si:
- Estás tratando con un pequeño número de conexiones a la vez
- Generalmente haces un procesamiento extenso para cada conexión
- Solo se trata de hosts locales, por lo que su conexión con ellos es rápida y confiable
- Le preocupa más optimizar el desarrollo que la ejecución
1. Bueno, técnicamente no es la única manera posible, pero la mayoría de las alternativas son relativamente feas: para ser más específico, creo que para cuando agregue el código para descubrir que hay un problema y luego resuelva el problema, usted '' Probablemente haya hecho más trabajo extra que si solo usara un zócalo sin bloqueo.
Su pregunta merece una discusión mucho más larga, pero aquí hay una breve apuñalamiento en una respuesta:
- El uso de sockets de bloqueo significa que solo un socket puede estar activo en cualquier momento en cualquier subproceso (porque bloquea mientras espera la actividad)
- usar sockets de bloqueo es generalmente más fácil que los sockets sin bloqueo (la programación asincrónica tiende a ser más complicada)
- podrías crear 1 hilo por zócalo como dijiste pero los hilos tienen una sobrecarga y son extremadamente ineficientes en comparación con las soluciones sin bloqueo;
- con sockets no bloqueantes podría manejar un volumen mucho mayor de clientes: podría escalar a cientos de miles en un solo proceso, pero el código se vuelve un poco más complicado
Con los zócalos sin bloqueo (en Windows) tiene un par de opciones:
- votación
- eventos basados
- E / S superpuesta
Las E / S superpuestas le proporcionarán el mejor rendimiento (miles de sockets / procesos) a expensas de ser el modelo más complicado de comprender e implementar correctamente.
Básicamente se trata de la complejidad del rendimiento frente a la programación.
NOTA
Aquí hay una mejor explicación de por qué usar un modelo de subproceso / socket es una mala idea:
En Windows, crear una gran cantidad de subprocesos es altamente ineficiente porque el planificador no puede determinar correctamente qué subprocesos deberían recibir el tiempo del procesador y cuáles no. Eso, junto con la sobrecarga de memoria de cada hilo, significa que se quedará sin memoria (debido al espacio de pila) y ciclos de procesador (debido a sobrecarga en la gestión de subprocesos) en el sistema operativo mucho antes de que se quede sin capacidad para manejar conexiones de socket .