这个“警报”错误意味着什么?

时间:2017-04-05 18:38:50

标签: c memory timer signals getrusage

我试图获取算法消耗的内存,所以我创建了一组函数,这些函数将在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()
  4. 我该如何解决这个问题?该警报信息意味着什么?

1 个答案:

答案 0 :(得分:2)

首先,将itimer设置为每10μs振铃是乐观的,因为10微秒实际上是一小段时间。尝试500μs(或者甚至20毫秒,即20000μs)而不是10μs。

  

以10毫秒的时间段停止执行

您编码的时间为10 micro 秒,而不是毫秒!

然后,您应该交换两行和代码:

signal(SIGALRM, medir_memoria);
setitimer(ITIMER_REAL, &t,0);

以便在第一个itimer响起之前设置信号处理程序。

我猜你的第一个itimer在安装信号处理程序之前响了。仔细阅读signal(7)time(7)SIGALRM的默认处理是终止。

BTW,衡量一些函数使用时间的更好方法是clock_gettime(2)clock(3)。感谢vdso(7)技巧,clock_gettime能够在我的i5-4690S台式电脑上获得不到50纳秒的时钟。

  

试图消耗内存

您可以考虑使用proc(5),例如快速打开,阅读和关闭 <{em> /proc/self/status/proc/self/statm等等。

(我猜你在Linux上)

顺便说一下,你的测量结果会令你失望:请注意,free(3)通常不会向内核释放内存(通过munmap(2) ...),只需标记&amp;管理该区域可由 future malloc(3)重复使用。您可能会考虑mallinfo(3)malloc_info(3),但请注意它不是异步信号安全的,因此无法从信号处理程序中调用。

(我倾向于认为你的方法存在严重缺陷)