Supongamos que tiene un programa que lee desde un socket. ¿Cómo se mantiene la tasa de descarga por debajo de un determinado umbral determinado?¿Cómo calificas el límite de una operación IO?
Respuesta
En la capa de aplicación (utilizando una API de estilo de socket Berkeley) solo mira el reloj, y lee o escribe datos a la velocidad que desea limitar.
Si solo lee 10kbps en promedio, pero la fuente está enviando más que eso, eventualmente todos los búferes entre él y usted se llenarán. TCP/IP lo permite, y el protocolo hará que el emisor se desacelere (en la capa de aplicación, probablemente todo lo que necesita saber es que, en el otro extremo, bloqueará las llamadas de escritura, las que no sean de bloqueo fallarán y las asincrónicas las escrituras no se completarán, hasta que haya leído suficientes datos para permitirlo).
En la capa de aplicación, solo puede ser aproximado: no puede garantizar límites duros, como "no más de 10 kb pasará un punto determinado de la red en cualquier segundo". Pero si realiza un seguimiento de lo que ha recibido, puede obtener el promedio correcto a la larga.
Suponiendo un transporte de red, basado en TCP/IP, los paquetes se envían en respuesta a los paquetes ACK/NACK que van por el otro camino.
Al limitar la tasa de paquetes que acusan recibo de los paquetes entrantes, a su vez se reducirá la velocidad a la que se envían los paquetes nuevos.
Puede ser un poco impreciso, por lo que es posiblemente óptimo para controlar la tasa de flujo descendente y ajustar la tasa de respuesta de forma adaptativa hasta que se encuentre dentro de un umbral confortable. (Esto sucederá realmente rápido, sin embargo, envía dosens of acks por segundo)
Si está leyendo desde un socket, no tiene control sobre el ancho de banda utilizado; está leyendo el buffer del sistema operativo de ese socket, y nada de lo que diga hará que la persona que escribe en el zócalo escriba menos datos (a menos que, por supuesto, haya elaborado un protocolo para eso).
Lo único que haría lentamente con la lectura sería llenar el búfer y provocar un eventual bloqueo en el extremo de la red, pero no tiene control sobre cómo y cuándo sucede esto.
Si realmente desea leer solamente tantos datos a la vez, se puede hacer algo como esto:
ReadFixedRate() {
while(Data_Exists()) {
t = GetTime();
ReadBlock();
while(t + delay > GetTime()) {
Delay()'
}
}
}
Los almacenamientos intermedios tienen valores máximos. ¿Cache? No hay memoria caché involucrada. –
Usted tiene, por supuesto, toda la razón. Eliminé las cosas de la memoria caché y agregué un poco sobre las memorias intermedias. – Branan
wget parece manejarlo con la opción de tasa --limit. Aquí hay de la página man:
Tenga en cuenta que Wget implementa el limitando por dormir la cantidad apropiada de tiempo después de una lectura de la red que se llevó a menos tiempo que el especificado por el tipo de . Finalmente, esta estrategia ocasiona que la transferencia TCP disminuya a aproximadamente la velocidad especificada. Sin embargo, puede tomar algún tiempo para lograr este equilibrio, por lo que no se sorprenda si la limitación de la tasa no funciona bien con archivos muy pequeños .
Como han dicho otros, el núcleo del sistema operativo está administrando el tráfico y simplemente está leyendo una copia de los datos de la memoria del kernel.Para limitar aproximadamente la velocidad de una sola aplicación, necesitas retrasar tus lecturas de los datos y permitir que los paquetes entrantes se almacenen en el kernel, lo que eventualmente ralentizará el reconocimiento de los paquetes entrantes y reducirá la velocidad en ese socket.
Si desea ralentizar todo el tráfico hacia la máquina, debe ir y ajustar los tamaños de sus búferes TCP entrantes. En Linux, afectaría este cambio al alterar los valores en/proc/sys/net/ipv4/tcp_rmem (leer tamaños de búfer de memoria) y otros archivos tcp_ *.
Es como cuando se limita un juego a un cierto número de FPS.
extern int FPS;
....
timePerFrameinMS = 1000/FPS;
while(1) {
time = getMilliseconds();
DrawScene();
time = getMilliseconds()-time;
if (time < timePerFrameinMS) {
sleep(timePerFrameinMS - time);
}
}
De esta manera, asegúrese de que la frecuencia de actualización del juego sea como máximo FPS. De la misma manera DrawScene puede ser la función utilizada para bombear bytes en la secuencia de socket.
Para añadir a la respuesta de Branan:
Si limita voluntariamente la velocidad de lectura en el extremo receptor, con el tiempo las colas se llenan en ambos extremos. Luego, el remitente bloqueará en su llamada de envío() o regresará de la llamada de envío() con una longitud de envío inferior a la duración esperada transferida a la llamada de envío().
Si el remitente no está preparado para tratar este caso durmiendo e intentando reenviar lo que no cabe en los búfers del sistema operativo, terminará teniendo problemas de conexión (el remitente puede detectar esto como un error) o perderá datos (el remitente puede descartar datos sin saber que no encajaban en los búferes del sistema operativo).
Configure los búferes de envío y recepción de zócalo pequeño, digamos 1k o 2k, de modo que el ancho de banda * demore el producto = el tamaño del búfer. Es posible que no pueda obtenerlo lo suficientemente pequeño a través de enlaces rápidos.
- 1. ¿Qué módulo de subprocesamiento debo usar para evitar que el disco IO bloquee la red IO?
- 2. Cómo vaciar el buffer io en Erlang?
- 3. Cómo aplanar IO [[String]]?
- 4. Perforce: cómo cancelar una operación de sincronización?
- 5. Haskell mónada: IO [doble] a [IO Doble]
- 6. ¿Cómo convierto una cadena en una lista en Io?
- 7. ¿Cómo solucionar el límite excedido de maxWarmingSearchers?
- 8. ¿Cómo se crea una subclase personalizada de IO en Ruby?
- 9. Cómo realizo IO dentro de una aplicación WAI (Warp)
- 10. Escribir una operación atómica
- 11. ¿XMLDocument.Guardar una operación atómica?
- 12. El estado de Linux async IO?
- 13. Llamar a una Monad de IO dentro de una Flecha
- 14. ¿Cómo hago el correcto manejo de errores IO :: Select?
- 15. ¿Cómo detecta el lenguaje Io el interbloqueo automático?
- 16. Haskell IO: No se pudo encontrar el tipo esperado `IO a0 'con el tipo real
- 17. cómo cancelar la operación fuera de operación creada con addOperationWithBlock?
- 18. ¿Hay alguna aplicación escrita en el lenguaje de programación Io? (O, distribuyendo aplicaciones Io.)
- 19. ¿Cómo ejecuto realmente una mónada StateT junto con IO?
- 20. Seleccione el segundo más grande de una tabla sin límite
- 21. Memoized IO function?
- 22. tiempo de espera establecido para una operación
- 23. ¿Cómo utiliza .NET los subprocesos IO o los puertos de terminación IO?
- 24. Cómo cancelar una operación de arrastrar marcador de Google Map?
- 25. ¿Está lanzando una operación costosa?
- 26. ¿Cómo puedo cancelar de inmediato una operación de curvatura?
- 27. Cómo cancelar una operación larga de la base de datos?
- 28. sin bloqueo-io vs bloqueo-io el rendimiento de los datos en bruto
- 29. Cómo hacer una operación de fusión de data.table
- 30. Es una operación atómica suficiente
¿No es necesario ir a la pila de TCP/IP de bajo nivel y pasar por alto la capa de socket estándar? – Branan