c++ - 获取子进程C++的执行结果

标签 c++ linux fork

我一直在尝试实现在线法官,但我陷入困境.. 我使用 fork 创建一个子进程,然后从子进程中使用系统命令启动我要测试的程序。

这是我用来测试评分器的程序。它处于无限循环中,但我只是注释该行以使其工作。

#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,您可以使用 kill(2) 向子进程发送信号,并通过 wait(2) 获取退出状态,如果它因使用 WTERMSIG 信号而退出。

问题可能是您正在使用 system(),因此评分器实际上在第三个​​进程中运行,而不是在子进程中运行。

N.B 就我个人而言,我不会将 system() 与这样的文件重定向一起使用,我会设置管道,然后在子级中使用 exec() ,因此评分器实际上在子级中运行。或者我就用我的 pstreams图书馆。

关于c++ - 获取子进程C++的执行结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11265305/

相关文章:

c++ - 将 QVariant 分配给 QVariant 时应用程序崩溃

c# - 将对象从 C# COM 库传递到 C++ 应用程序时如何修复内存泄漏

c++ - 压缩问题,zlib?

java - 如何在 Linux 上安装 Eclipse

c - 在控制台中移动光标和打印字符不适用于 sleep

linux - 如果使用 appimage 安装了 neovim,如何使用 nvim 命令?

ruby - 如何使用 Daemons gem 获取第一个任务的 pid?

linux - Linux 中进程间如何共享代码段?

c - WC 没有执行任何操作

c++ - Using getopt when options have options C++