Что означает эта "тревожная" ошибка?
Я пытаюсь получить память, потребляемую алгоритмом, поэтому я создал группу функций, которые будут останавливать выполнение в течение 10 миллисекунд, чтобы позволить мне читать память с помощью функции getrusage (). Идея состоит в том, чтобы установить таймер, который подаст сигнал тревоги процессу, который будет получен обработчиком medir_memoria ().
Тем не менее, программа останавливается посередине с этим сообщением:
[1] 3267 alarm ./memory_test
Код для чтения памяти:
#include "../include/rastreador_memoria.h"
#if defined(__linux__) || defined(__APPLE__) || (defined(__unix__) && !defined(_WIN32))
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <signal.h>
#include <sys/resource.h>
static long max_data_size;
static long max_stack_size;
void medir_memoria (int sig)
{
struct rusage info_memoria;
if (getrusage(RUSAGE_SELF, &info_memoria) < 0)
{
perror("Not reading memory");
}
max_data_size = (info_memoria.ru_idrss > max_data_size) ? info_memoria.ru_idrss : max_data_size;
max_stack_size = (info_memoria.ru_isrss > max_stack_size) ? info_memoria.ru_isrss : max_stack_size;
signal(SIGALRM, medir_memoria);
}
void rastrear_memoria ()
{
struct itimerval t;
t.it_interval.tv_sec = 0;
t.it_interval.tv_usec = 10;
t.it_value.tv_sec = 0;
t.it_value.tv_usec = 10;
max_data_size = 0;
max_stack_size = 0;
setitimer(ITIMER_REAL, &t,0);
signal(SIGALRM, medir_memoria);
}
void detener_rastreo ()
{
signal(SIGALRM, SIG_DFL);
printf("Data: %ld\nStack: %ld\n", max_data_size, max_stack_size);
}
#else
#endif
Функция main () работает, вызывая их все в следующем порядке:
- rastrear_memoria ()
- Функция алгоритма, который я тестирую
- detener_rastreo ()
Как я могу решить это? Что означает это тревожное сообщение?
1 ответ
Во-первых, установка итимера для звонка каждые 10 мкс является оптимистичной, поскольку десять микросекунд - это действительно небольшой интервал времени. Попробуйте сначала 500 мкс (или, возможно, даже 20 миллисекунд, то есть 20000 мкс) вместо 10 мкс.
остановить выполнение в течение 10 миллисекунд
Вы кодировали в течение 10 микросекунд, а не миллисекунд!
Затем вы должны обменять две строки и код:
signal(SIGALRM, medir_memoria);
setitimer(ITIMER_REAL, &t,0);
так что обработчик сигнала устанавливается до того, как первый итимер зазвонит.
Полагаю, ваш первый итимер зазвонил до того, как был установлен обработчик сигнала. Прочитайте внимательно сигнал (7) и время (7). Обработка по умолчанию SIGALRM
это прекращение.
Кстати, лучший способ измерить время, используемое некоторой функцией, это clock_gettime(2) или clock (3). Благодаря трюкам vdso(7), clock_gettime
может получить некоторые часы менее чем за 50 наносекунд на моем настольном компьютере i5-4690S.
пытаясь получить память потребляется
Вы можете рассмотреть использование proc(5), например, открытие, чтение и закрытие быстро /proc/self/status
или же /proc/self/statm
так далее....
(Я думаю, вы на Linux)
Кстати, ваши измерения вас разочаруют: обратите внимание, что довольно часто free(3) не освобождает память для ядра (через munmap (2)...), а просто помечает и управляет этой зоной для повторного использования в будущем malloc(3), Вы можете рассмотреть mallinfo(3) или malloc_info(3), но заметьте, что это не безопасно для асинхронного сигнала, поэтому не может быть вызвано из обработчика сигнала.
(Я склонен полагать, что ваш подход глубоко испорчен)