Для нагрузочного теста моего приложения (под Linux) я ищу инструмент, который выводит данные на стандартный вывод с определенной скоростью (например, 100 байт / с), чтобы я мог передать вывод в netcat, который отправляет его моему заявление. Какой-то вариант для dd был бы идеальным, но пока ничего не нашел. На самом деле не имеет значения, какие данные печатаются (байты NUL в порядке). Какие-нибудь намеки?





Если у вас все в порядке с получением всех сотен байтов за раз, вы можете сделать цикл с sleep и простым старым echo в оболочке, по крайней мере, с первой попытки.
хорошая идея - что-то вроде «while [true]; do echo -n« 1234567890 »; usleep 10000; done» уже работает.
Что ж, теперь я использую nuttcp для «настоящих» нагрузочных тестов. У него довольно низкие накладные расходы, поэтому тестовая система не сильно мешает.
Я написал быструю программу, которая принимает один аргумент, сколько символов A выводить на стандартный вывод в секунду (отрицательный аргумент означает отсутствие ограничения скорости). Надеюсь это поможет! :-) (В GNU libc вам нужно будет связать вашу программу с -lrt.)
Обновлено: исправлено для печати точки по умолчанию, если не указан второй аргумент, и в этом случае используется первый его символ. (А это означает, что если вы хотите напечатать символ NUL, просто укажите пустую строку в качестве второго аргумента. :-))
#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);
}
}
В последней версии теперь вы можете указать 0 в качестве скорости. Технически это не ждет «вечно» (как и должно быть математически); скорее, он ждет до конца time_t (январь 2038 года, на платформах с 32-битным time_t). Однако ждать еще довольно долго. :-D
Хороший материал - спасибо! Как насчет того, чтобы разместить его на каком-нибудь сайте контроля версий (github, launchpad, sourceforge ...), чтобы люди могли добавлять изменения? Кроме того, я думаю, что для повышения производительности было бы полезно написать () сразу целый блок данных.
Я намеренно использовал write () без буферизации, чтобы данные гарантированно поступали с постоянной скоростью. Чтобы использовать буферизацию, измените вызов write () на putchar (* argv [2]). :-) Я посмотрю, что я могу сделать с общедоступным контролем версий ....
Кроме того, если вы используете что-то маленькое для скорости, например 100 (как в исходном вопросе), большую часть времени займет сон, а не запись. Я написал функцию sleeptill () специально, чтобы избежать "задержки времени" из-за затраченного времени, например, на запись.
Хорошо, это не github или что-то в этом роде, но, надеюсь, поможет: refactormycode.com/codes/…
Думаю, это то, что вам действительно нужно: Просмотрщик труб
Использование <fast input> | pv -qL <rate>[k|m|g|t] | <rate-limited output> ограничит канал до запрошенной скорости.
Корреспондент прокомментировал мне, что использование канала для netcat может означать, что канал может быть ограничивающим фактором. Таким образом, более надежно писать прямо в сокет с той скоростью, которую вы ищете.