2012-05-18 24 views
34

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?¿Por qué debería usar enchufes que no bloquean o bloquean?

Respuesta

29

Su pregunta merece una discusión mucho más tiempo, pero aquí hay un corto puñalada en una respuesta:

  • usando sockets de bloqueo significa que sólo un enchufe puede estar activo en cualquier momento y en cualquier un hilo (ya que bloquea a la espera para la actividad)
  • usando sockets de bloqueo es generalmente más fácil que tomas no bloqueantes (programación asincrónica tiende a ser más complicado)
  • puede crear 1 hilo por socket como ha afirmado, pero las discusiones tienen los gastos generales y son extremadamente ineficientes en comparación con el soluciones sin bloqueo;
  • con tomas no bloqueo que podí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 manguitos no bloqueantes (en Windows) que tiene un par de opciones:

  • de votación
  • eventos basados ​​
  • que solapan/S

Las E/S sobrepuestas 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é el uso de un modelo de rosca/conector es una mala idea:

En las ventanas, la creación de un gran número de hilos es muy ineficiente debido a que el programador no puede Determine 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 .

+0

Si se está ejecutando en una caja de 80 vías, usted puede rasgar a cabo cientos de hilos ningún problema. –

+0

@John: Solo porque es posible crear cientos de hilos (si tienes suficiente memoria) no significa que sea una buena idea. De hecho, es una mala idea! –

+9

Mi punto, ciertamente no bien hecho, es que no se puede dibujar una línea arbitraria en 20 y llamar a cualquier número de hilos más allá de ese "mal". –

8

Voy a ir en el registro diciendo que para casi cualquier cosa, excepto los programas de juguete, debe utilizar enchufes sin bloqueo como una cuestión de rutina.

Los sockets de bloqueo causan un problema grave: si la máquina en el otro extremo (o 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 manera 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 de limpiar después de recuperar los recursos asignados.Los sockets no bloqueantes hacen que sea trivial abortar una llamada cuando/si es necesario, sin haciendo algo al hilo que realizó la llamada.

Es posible hacer que los sockets de bloqueo funcionen bien si utiliza un modelo de proceso múltiple. 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. Sin embargo, esto puede ser una opción viable, especialmente si:

  1. Usted está tratando con un pequeño número de conexiones a la vez
  2. Por lo general, hacer una amplia procesamiento para cada conexión
  3. Usted está tratando solamente con los anfitriones locales para que su conexión con ellos es rápido y fiable
  4. Usted está más preocupado con la optimización del desarrollo de la ejecución

1. Bueno, técnicamente no es el único posible, pero la mayoría de las alternativas son relativamente feas, para ser más específicas, creo que para cuando agregue el código para descubrir que hay un problema, y ​​luego arregle el problema, probablemente haya hecho más trabajo extra que si solo usara un socket sin bloqueo.

+6

Es posible abortar una operación de socket bloqueado sin terminar el hilo bloqueado desconectando el socket de otro contexto de hilo. Eso causará que la operación bloqueada falle con un código de error, luego el hilo bloqueado puede avanzar y hacer otras cosas, como la limpieza normal. –

Cuestiones relacionadas