2008-10-28 7 views
6

Para una prueba de carga de mi aplicación (en Linux), estoy buscando una herramienta que muestre datos en stdout a una velocidad específica (como 100 bytes/s), para que pueda canalizar la salida a netcat que lo envía a mi aplicación. Alguna opción para dd sería ideal, pero no encontré nada hasta ahora. Realmente no importa qué tipo de datos se imprimen (los bytes NUL son correctos). ¿Algún consejo?hacer salida estándar con velocidad específica

+0

Un corresponsal me ha comentado que usar una tubería en netcat podría significar que la tubería podría ser un factor limitante. Por lo tanto, es más confiable escribir directamente en el socket a la velocidad que busca. –

Respuesta

3

creo que esto es lo que realmente quiere: Pipe Viewer

El uso de <fast input> | pv -qL <rate>[k|m|g|t] | <rate-limited output> limitará la tubería a la tasa solicitada.

2

Si está bien con obtener todos los cientos de bytes a la vez, puede hacer un ciclo con sleep y echo en el shell como primer intento al menos.

+0

buena idea - algo así como "while [true]; echo echo -n" 1234567890 "; usleep 10000; done" ya funciona. – oliver

0

Bueno, ahora estoy usando nuttcp para hacer pruebas de carga "reales" en su lugar. Parece tener una sobrecarga bastante baja, por lo que el sistema de prueba no está demasiado alterado.

5

Escribí un programa rápido que toma un argumento, cuántos caracteres A imprimir en salida estándar por segundo (argumento negativo significa que no hay límite de velocidad). ¡Espero que esto ayude! :-) (En GNU libc, necesitará vincular su programa con -lrt.)

Editar: revisado para imprimir punto por defecto, a menos que se especifique un segundo argumento, en cuyo caso se utiliza el primer carácter de ese. (Y eso significa que, si se desea imprimir el carácter NUL, basta con especificar una cadena vacía como el segundo argumento :-).)

#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <unistd.h> 

int 
sleeptill(const struct timespec *when) 
{ 
    struct timespec now, diff; 

    clock_gettime(CLOCK_REALTIME, &now); 
    diff.tv_sec = when->tv_sec - now.tv_sec; 
    diff.tv_nsec = when->tv_nsec - now.tv_nsec; 
    while (diff.tv_nsec < 0) { 
     diff.tv_nsec += 1000000000; 
     --diff.tv_sec; 
    } 
    if (diff.tv_sec < 0) 
     return 0; 
    return nanosleep(&diff, 0); 
} 

int 
main(int argc, char **argv) 
{ 
    double rate = 0.0; 
    char *endp; 
    struct timespec start; 
    double offset; 

    if (argc >= 2) { 
     rate = strtod(argv[1], &endp); 
     if (endp == argv[1] || *endp) 
      rate = 0.0; 
     else 
      rate = 1/rate; 

     if (!argv[2]) 
      argv[2] = "."; 
    } 

    if (!rate) { 
     fprintf(stderr, "usage: %s rate [char]\n", argv[0]); 
     return 1; 
    } 

    clock_gettime(CLOCK_REALTIME, &start); 
    offset = start.tv_nsec/1000000000.0; 

    while (1) { 
     struct timespec till = start; 
     double frac; 
     double whole; 

     frac = modf(offset += rate, &whole); 
     till.tv_sec += whole; 
     till.tv_nsec = frac * 1000000000.0; 
     sleeptill(&till); 
     write(STDOUT_FILENO, argv[2], 1); 
    } 
} 
+1

Con la última revisión, ahora puede especificar 0 como la tasa. Técnicamente, no espera "para siempre" (como debería, matemáticamente); más bien, espera hasta el final de time_t (enero de 2038, en plataformas con un time_t de 32 bits). Sin embargo, aún es un buen momento para esperar. :-D –

+0

Cosas agradables, ¡gracias! ¿Qué hay de ponerlo en algún sitio de control de revisiones (github, launchpad, sourceforge ...) para que la gente pueda agregar cambios? Además, creo que para el rendimiento sería útil escribir() un bloque completo de datos a la vez. – oliver

+0

Utilicé deliberadamente write() sin almacenamiento en memoria intermedia, por lo que se garantiza que los datos llegarán a un ritmo constante. Para usar el almacenamiento en búfer, cambie la llamada de escritura() a putchar (* argv [2]). :-) Veré qué puedo hacer sobre el control de revisión pública ... –

Cuestiones relacionadas