Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Los Sockets No Bloqueantes Funcionan Por Hardware?

Iniciado por fiero, 28 de Febrero de 2005, 05:57:37 PM

« anterior - próximo »

fiero

 Bueno, el título del post no es muy aclaratorio, a ver si me explico. No me queda muy claro si un socket no bloqueante consume cpu o no. Es decir, por lo que he leido, puedo recibir datos sin que recv() se bloquee, y cuando los datos sean recibidos, el sockect generará una excepción que puedo interceptar. Pero, para recibir esos datos y rellenar el buffer de lectura, ¿la función recv() genera un hilo de ejecución a parte o hay alguna circuitería que se encarga de eso liberando a la cpu?

No me explico muy bien, ¿alguien me puede ayudar con la duda?

un saludo

PD: enhorabuena por los juegos en 1 dia, yo soy un cagao....
www.videopanoramas.com Videopanoramas 3D player

ethernet

 Creo que mezclas términos, por un lado están los sockets no bloqueantes y por otro los asincronos (personalemnte solo conozco la implementación de windows).

Cuando tú pones el socket no bloqueante y este recibe algo, al hacer un recv sobre él te retornará los datos correspondientes, si no tiene datos retorna error y setea la variable de control de errores correspondiente a un valor que indica que no había datos, con esto evitas confundir lo no existencia de datos con un error.

En cuanto a lo que comentas de si crea un hilo aparte o yo qué sé, habría que mirar la implementación concreta de la pila TCP en el SO que estés tratando. En cualquier caso es algo que no debe preocuparte de como hace o deja de hacer, es transparente para ti. Si te preocupa lo del buffer debes saber que sea bloqueante o no al final siempre tiene que haber un buffer que recoja los datos que van llegando.

saludos

ZeruGiran

 >socket no bloqueante consume cpu o no.

Si lo implementas bien un socket bloqueante consume menos recursos.

>puedo recibir datos sin que recv() se bloquee, y cuando los datos sean recibidos, el sockect generará una excepción que puedo interceptar.

Te refieres a usar SELECT()?

Hay distintas formas de hacer las cosas, cada una con sus ventajas y desventajas.

A mi parecer, usar sockets en modo bloqueante es mucho mejor. Por el tema de que no usan recursos mientras estan bloqueados.

Luego tienes dos opciones, usar SELECT() para capturar las "excepción" (por cierto hay excepciónes generadas por software y las hay generadas por hardware, las de los sockets son por software) o meter los recv() en threads.

Cada una de las dos tiene sus ventajas y desventajas: Usar Select() es mucho mas sencillo y su desempeño es algo mas rapido. Usando Threads entraras a la programacion concurrente, es mucho mas complicado, tendras que leer sobre Mutex y Semaforos y considerar que es sumamente complicado debugear el codigo de un programa concurrente. Pero tiene sus ventajas usar Threads, si tienes un intel con hiperthreading aprobechas las caracteristica de tu procesador, o mejor aun si tienes dos o mas procesadores, tu programa realmente hara uso de ellos. En cambio un programa que no usa threads solo usa un procesador a la vez. En aplicaciones grandes, que exploten muchos conecciones simultaneas el rendimiento de los Threads es algo superior a usar Select().

En resumen, si tu aplicacion sera grande, usa Threads. Pero si solo vaz a usar algunos pocos Sockets usa Select().

Y hay una tercera opcion :) usa una libreria de Sockets, es decir no los implementes a mano, no reescribas algo que ya han hecho otras personas.

Aca hay una libreria de sockets en la que estamos trabajando, es 100% funcional:

SolarSockets
MIra los Ejemplos

Saludos.

fiero

 Actualmente utilizo sockets bloqueantes desde distinto thread al principal. Pero si como dices no se gana nada utizando no bloqueantes lo dejo como está.

Citarhay excepciónes generadas por software y las hay generadas por hardware, las de los sockets son por software
Si es así, el procesador principal es el que está rellenando el buffer de lectura (al utilizar recv), esa era mi duda.


Tengo que mirarme los asincronos que menciona ethernet, que no se exactamente la diferencia entre unos y otros.

un saludo y gracias por las respuestas
www.videopanoramas.com Videopanoramas 3D player

senior wapo

 Los sockets asíncronos (en windows) son los que menos pérdida de rendimiento presentan por sí mismos. Lo más ineficiente, sockets no bloqueantes, con polling (nada que ver con poll de Linux). Los sockets bloqueantes supuestamente, en teoría,  son eficientes también (no consumen proceso mientras están a la espera), pero:

El problema de los bloqueantes es que select() es muy ineficiente en la implementación de windows.
La alternativa si usas bloqueantes es  usar threads, pero ahí incurres en la carga extra de usar threads. Desconozco la eficiencia de windows gestionando tantos threads ya que nunca he hecho profiling de un servidor en producción con mucha carga de threads (cientos? miles? suponer puedo suponer como todos, pero verlo con mis propios ojos no lo he hecho).  

Luego tienes los sockets asincronos, con y sin overlapped I/O. En teoría son los más eficientes (bajo windows), pero es más coñazo programarlos. Estos últimos, asincronos con overlapped I/O, son los sockets de los que hablabas, que generan un evento al terminar la operación. Y si, el trabajo lo realiza la CPU. La ventaja: un solo hilo de ejecución puede procesar muchos sockets sin usar select ni hacer polling, ya que recibe un evento cuando el socket está listo para ser procesado. Simplemente procesas la cola de eventos (como haces ocn los mensajes de ventana).

La verdad es que si estas haciendo un cliente o un miniservidor te conviene ir a lo que te resulte más sencillo.
Si estás haciendo un servidor UDP de juegos, ya te ahorro yo los sudores: la manera más eficiente es un solo socket UDP con un buffer (de sistema) del tamaño del Everest.

Para más info, googlea C10k y la ayuda de ISAPI del IIS (creo que era la guia de ISAPI), que explica cuando y como elegir overlapped  en IIS (Internet Information Server, el servidor web de Microsoft).


Un saludo.

zupervaca

 yo uso los ultimos que mencionas, son los que menos consumen, si quieres probarlos rapidamente sin implementar nada usa la clase casyncsocket de mfc (si usas visual c++ claro), si lo depuras con suerte veras que alguna vez lo pillas enviando mensajes a una ventana oculta en tu aplicacion  ;)  

ethernet

 En msnd hay unos tropecientos artículos de sockets eficientes para windows.

saludos






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.