【问题标题】:Memory usage of child process in CC中子进程的内存使用情况
【发布时间】:2015-07-27 14:34:10
【问题描述】:

我阅读了article 中关于 C 中内存使用计算的内容,但遇到了问题。

我编写了一个简单的测试程序,它可以运行超过一秒并使用超过 1 KB 的内存。

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int a;
int f[1000000];
sleep(1);
 scanf("%d",&a);
 printf("%d %d\n",a/10,a%10);

return 0;
}

然后我将它编译成一些main.exe 并检查文章中的程序操作

pid = fork();
if (pid == 0) 
{
    struct rlimit rlim;
    rlim.rlim_cur = rlim.rlim_max = TIME_LIMIT;
    setrlimit(RLIMIT_CPU, &rlim);
    execv("./main.exe",NULL);
}
else 
{
        struct rusage resource_usage;
        // set arbitrary lower limit value of memory used
        int memory_used = 128;
        pid_t pid2;

        do {
            memory_used = max(memory_used, get_memory_usage(pid));
            if ((memory_used > memory_limit)
                kill(pid, SIGKILL);

           // wait for the child process to change state
            pid2 = wait4(pid, &status, WUNTRACED | WCONTINUED, &resource_usage);
        } while (pid2 == 0);
}

以及来自文章的函数get_memory_usage()

int get_memory_usage(pid_t pid) {
    int fd, data, stack;
    char buf[4096], status_child[NAME_MAX];
    char *vm;

    sprintf(status_child, "/proc/%d/status", pid);
    if ((fd = open(status_child, O_RDONLY)) < 0)
        return -1;

    read(fd, buf, 4095);
    buf[4095] = '\0';
    close(fd);

    data = stack = 0;

    vm = strstr(buf, "VmData:");
    if (vm) {
        sscanf(vm, "%*s %d", &data);
    }
    vm = strstr(buf, "VmStk:");
    if (vm) {
        sscanf(vm, "%*s %d", &stack);
    }

    return data + stack;    
}

但是字符串中的问题,其中pid2 = wait4(pid, &amp;status, WUNTRACED | WCONTINUED, &amp;resource_usage);while 只进行一次迭代并等待进程结束。但我需要计算内存,rusage resource_usage 不要给我这个信息。我怎样才能使while 在子进程运行并在他停止的地方停止时工作。 当他 ZOMBIE 时,子进程的状态有更多问题。它不给记忆。我也需要抓住它。因为如果对于我的main.exe 我使用这个测试程序:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   int a;
   int f[1000000];
   sleep(1);
   scanf("%d",&a);
   printf("%d %d\n",a/10,a%10);
   return 0;
}

当我在无限while 中从get_memory_usage 执行一些输出时,它会显示所有/proc/[pid]/status 输出。我明白了,那个子进程是

Name:   check.exe
State:  R (running)

然后它会

Name:   main.exe
State:  Z (zombie)

这意味着proc 无法捕获 main.exe 正在运行的信息。

【问题讨论】:

  • wait4() 返回:-1 表示发生了一些故障,0 表示没有发生状态更改,否则返回子进程的 pid。建议检查 (-1 or pid of child)

标签: c linux memory fork


【解决方案1】:

根据waitpid() 手册页,您对wait4() 的调用会阻塞,直到进程停止,或在停止后再次恢复。这与阻塞等待输入不同,它意味着它已被信号(SIGSTOP)停止。

您需要的是WNOHANG,它会阻止您的wait4() 并使其立即返回,可能像这样:

do 
{
   // All the stuff you want to do
   pid2 = wait4(pid, &status, WNOHANG, &resource_usage);
} while (pid2 == 0);

NB 我根本没有测试过上面的内容,甚至没有编译过。

【讨论】:

  • 我试图将它改成这样:while (1) { dir = opendir(direc); if (dir==NULL) { printf("1"); break; } current_memory=get_memory_usage(pid); memory_used = max(memory_used,current_memory); if (memory_used &gt; MEMORY_LIMIT) { res_code = 2; kill(pid, SIGKILL); } } 但是这个循环本身就中断了。不要打印 1,然后中断。我如何使用WNOHANG
  • WNOHANG 是您在wait4() 中使用的一个选项
  • 我试过 pid2 = wait4(pid, &amp;status, WNOHANG, &amp;resource_usage); 但是当我在第 198 次迭代中输出时,它会在第 199 次迭代中写入 Name: check.exe State: R (running),它会写入 Name: main.exe State: Z (zombie)VmData: 176 kB VmStk: 88 kB 检查是我从检查运行的所有程序的标准.我认为这是检查 fork 在执行 main 之前使用的一些最小内存。如何抓住主线?
  • 你的分叉进程是否直接退出?
  • 直道是什么意思? pid=fork(); if (pid==0) { exec(); } else { calculate..}我在帖子中编写代码。
猜你喜欢
  • 2010-10-19
  • 2012-11-16
  • 1970-01-01
  • 1970-01-01
  • 2016-03-18
  • 2015-03-11
  • 1970-01-01
  • 2016-05-30
  • 2011-10-09
相关资源
最近更新 更多