Cでのメモリ使用量の計算に関する記事を読みましたが、問題があります。
私は簡単なテストプログラムを作成します。これは1秒以上動作し、1KB以上のメモリを使用する可能性があります。
#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, &status, WUNTRACED | WCONTINUED, &resource_usage);
。while
反復を1回だけ行い、プロセスが終了するのを待ちます。しかし、私はメモリを計算する必要があり、rusage resource_usage
この情報を教えてくれません。while
子プロセスが実行されているときに動作し、停止したところで停止するよりも、どうすれば作成できますか。彼がゾンビをしているとき、子プロセスのステータスにはもっと問題があります。それは記憶を与えません。私もそれを捕まえる必要があります。私の場合、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;
}
get_memory_usage
infiniteから出力を行うとwhile
、すべての/proc/[pid]/status
出力が表示されます。なるほど、その子プロセスは
Name: check.exe
State: R (running)
その後、それは
Name: main.exe
State: Z (zombie)
これは、proc
main.exeが実行されている場所で情報を取得できないことを意味します。
waitpid()のマニュアルページによると、wait4()
プロセスへの呼び出しは、プロセスが停止するまでブロックするか、停止した後に再開します。これは、入力の待機をブロックすることと同じではなく、信号(SIGSTOP
)によって停止されたことを意味します。
必要なのは、ブロックWNOHANG
を停止しwait4()
、おそらく次のようにすぐに戻るようにすることです。
do
{
// All the stuff you want to do
pid2 = wait4(pid, &status, WNOHANG, &resource_usage);
} while (pid2 == 0);
注意:私は上記をまったくテストしておらず、コンパイルもしていません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加