Что означает эта "тревожная" ошибка?

Я пытаюсь получить память, потребляемую алгоритмом, поэтому я создал группу функций, которые будут останавливать выполнение в течение 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 () работает, вызывая их все в следующем порядке:

  1. rastrear_memoria ()
  2. Функция алгоритма, который я тестирую
  3. 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), но заметьте, что это не безопасно для асинхронного сигнала, поэтому не может быть вызвано из обработчика сигнала.

(Я склонен полагать, что ваш подход глубоко испорчен)

Другие вопросы по тегам