2
我一直在嘗試實現一個在線裁判,但我被卡住了.. 我用fork創建一個子進程,然後從子進程中使用系統命令啓動我應該測試的程序。獲取子進程的執行結果C++
這是我用來測試分級機的程序。它處於一個無限循環中,但我只是評論這條線以使其工作。
#include <stdio.h>
int main() {
int a, b;
scanf ("%d %d", &a, &b);
while (1);
printf ("%d\n", a + b);
return 0;
}
我編碼平地機至今
struct timeval start, end;
struct rlimit rl, default_memory, default_time;
getrlimit (RLIMIT_AS, &default_memory);
getrlimit (RLIMIT_CPU, &default_time);
pid_t pid = fork();
gettimeofday (&start, NULL);
if (pid < 0) printf ("Error\n");
else if (pid == 0) { // child process
if (memory_limit > 0) {
rl.rlim_cur = rl.rlim_max = memory_limit;
setrlimit (RLIMIT_AS, &rl);
}
if (time_limit > 0) {
rl.rlim_cur = rl.rlim_max = time_limit/1000 + 1;
setrlimit (RLIMIT_CPU, &rl);
}
ptrace (PTRACE_TRACEME, pid, NULL, NULL);
system ("./sum <in.txt> out.txt");
setrlimit (RLIMIT_CPU, &default_time);
setrlimit (RLIMIT_AS, &default_memory);
}
else { // parent process
int *status;
// Is this ok?
// Because here http://linux.die.net/man/2/ptrace it says that
// PTRACE_GETSIGINFO is used to get information about the signal that
// caused the stop. And I'm interested If the program was killed because of
// rlimit (exceeding time or memory limit) or if it was something else.
ptrace (PTRACE_GETSIGINFO, pid, NULL, NULL);
if (wait (status) == -1) return 1; // waiting for the child process to finish
if (WIFSIGNALED (status)) {
int exit_signal = WTERMSIG (status);
printf ("Terminated with signal: %d.\n", exit_signal);
switch (exit_signal) {
case 0:
printf ("OK\n");
break;
case SIGSEGV: // RLIMIT_AS -- SIGSEGV is sent, when the memory limit is exceeded
printf ("Memory Limit Exceeded\n");
break;
case SIGXCPU: // RLIMIT_CPU -- when soft limit is reached SIGXCPU is sent
case SIGKILL: // when hard limit is reached SIGKILL is sent
printf ("Time Limit Exceeded\n");
break;
default: // I didn't handle all the signals, so I made everything else a run time error
printf ("Run Time Error\n");
break;
}
}
ptrace (PTRACE_KILL, pid, NULL, NULL); // Kill the process If it is not killed
gettimeofday (&end, NULL); // This is working fine
double time = (end.tv_sec - start.tv_sec) + 1e-6 * (end.tv_usec - start.tv_usec);
printf ("%lf\n", time);
}
感謝您的回覆.. 好吧,我刪除了ptrace ..但是這並沒有改變enything ..我這裏的代碼只會在超過某個限制時殺死進程,但它不會告訴我哪個。這是最大的問題:( – user1410971
看到我編輯的答案,孩子沒有得到信號,_grand_子進程,system()調用啓動的那個,孩子只是等待它完成 –
..並且乾淨地退出,你可以試着讓孩子使用system()的返回值作爲退出狀態。 –