2008-10-28 15 views
6

Für einen Belastungstest meiner Anwendung (unter Linux), suche ich nach einem Werkzeug, das Daten auf stdout mit einer bestimmten Rate (wie 100 Bytes/s) ausgibt, damit ich pipen kann die Ausgabe an netcat, die es an meine Anwendung sendet. Eine Option für dd wäre ideal, aber bisher habe ich nichts gefunden. Es spielt keine Rolle, welche Art von Daten gedruckt werden (NUL-Bytes sind in Ordnung). Irgendwelche Hinweise?do stdout Ausgabe mit bestimmter Geschwindigkeit

+0

Ein Korrespondent hat zu mir kommentiert, dass die Verwendung eines Rohrs zu Netcat bedeuten könnte, dass das Rohr ein begrenzender Faktor sein könnte. Es ist daher zuverlässiger, direkt mit der Rate, die Sie suchen, in den Socket zu schreiben. –

Antwort

3

Ich glaube, das ist das, was Sie wirklich wollen: Pipe Viewer

Mit <fast input> | pv -qL <rate>[k|m|g|t] | <rate-limited output> wird die Pipe auf die angeforderte Rate begrenzt.

2

Wenn Sie alle hundert Bytes gleichzeitig erhalten, können Sie als ersten Versuch zumindest eine Schleife mit sleep und normalem echo in der Shell ausführen.

+0

gute Idee - etwas wie "während [wahr]; echo -n" 1234567890 "; usleep 10000; done" funktioniert bereits. – oliver

0

Nun, ich benutze jetzt Nuttcp, um "echte" Belastungstests stattdessen zu machen. Es scheint einen geringen Overhead zu haben, so dass das Testsystem nicht zu sehr gestört wird.

5

Ich schrieb ein schnelles Programm, das ein Argument dauert, wie viele A Zeichen auf Standardausgabe pro Sekunde (negatives Argument bedeutet keine Ratenbegrenzung) zu drucken. Hoffe das hilft! :-) (Unter GNU libc müssen Sie Ihr Programm mit -lrt verknüpfen.)

Bearbeiten: überarbeitet, um Punkt standardmäßig zu drucken, außer ein zweites Argument angegeben ist, in welchem ​​Fall das erste Zeichen davon verwendet wird. (Und das bedeutet, wenn Sie das NUL-Zeichen ausdrucken möchten, nur eine leere Zeichenfolge als zweites Argument angeben :-).)

#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

Mit der neuesten Version können Sie jetzt 0 als Rate angeben. Technisch gesehen wartet es nicht "für immer" (wie es sollte, mathematisch); es wartet vielmehr bis zum Ende von time_t (Januar 2038, auf Plattformen mit einer 32-bit time_t). Es ist jedoch noch eine Weile zu warten. :-D –

+0

Schöne Sachen - danke! Wie wäre es mit der Installation auf einer Revisionskontrollseite (github, launchpad, sourceforge ...), damit die Leute Änderungen hinzufügen können? Auch ich denke, für die Leistung wäre es nützlich,() einen ganzen Datenblock auf einmal zu schreiben. – oliver

+0

Ich benutzte absichtlich write() ohne Pufferung, so dass die Daten garantiert mit einer konstanten Rate kommen. Um die Pufferung zu verwenden, ändern Sie den Aufruf write() in putchar (* argv [2]). :-) Ich werde sehen, was ich tun kann über öffentliche Revisionskontrolle .... –