【问题标题】:wait4 do not block parent threadwait4 不阻塞父线程
【发布时间】:2013-07-17 00:23:07
【问题描述】:

我有以下两个源文件

loop.c 的可执行文件名为loop

int main() {
    while(true);
    return 0;
}

run.c 的可执行文件名为run

int main() {
    pid_t child_pid = fork();

    int status;
    struct rusage info;

    if (child_pid == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("loop", "loop", NULL);
        exit(0);
    }

    wait4(child_pid, &status, 0, &info);

    puts("Child exited");
    printf("%ld\n", info.ru_utime.tv_usec);

    return 0;
}

我已经编译了这两个程序并运行了run 程序。为什么终止了?我读过wait4 suspend,但实际上并没有。当我执行ps 时,程序loop 正在运行,而run 没有(它不在ps 中,终端似乎通过提供输出来完成它的工作)。

我错过了什么吗?

PS

如果重要的话,我会使用 gnu g++ 编译器。

【问题讨论】:

    标签: c linux multithreading pthreads


    【解决方案1】:

    我想问题就在这里

    ptrace(PTRACE_TRACEME, 0, NULL, NULL);
    

    这里

    wait4(child_pid, &status, 0, &info);
    

    如果进程状态发生变化,wait4(顺便说一句已弃用)返回控制权。

    ptrace(PTRACE_TRACEME 在某些情况下强制子发送到父 SIGTRAP 发生,并且每次 wait4、waitpid 和类似的函数都将控制权返回给您, 您需要使用 WIFEXITED 来区分子进程的退出和 SIGTRAP 条件。

    您可以通过将 wait4 调用替换为:

        if (wait4(child_pid, &status, 0, &info) < 0) {
            perror("wait4 failed");
        } else if (WIFEXITED(status)) {
            printf("process exit\n");
        } else
            printf("child just send signal\n");
    

    【讨论】:

    • 感谢您的建议,我将 wait4 包裹在无限循环中,实际上它运行了一次。顺便说一句,我应该用什么代替wait4?我真的需要知道子线程的执行时间。
    • 在您的变体中,您可以使用 getrusage(RUSAGE_CHILDREN.
    • 顺便说一下,您可以找到具有类似模式 ptrace + waitpid 的工作程序,但这个程序可以工作,在这里:habrahabr.ru/post/111266。这是关于跟踪系统调用的。即使你不懂俄语,文章中的 C 代码也足以让你有所了解。
    • 谢谢你现在我明白如何处理我的问题了。被评为最佳答案。
    • 如果可能的话,我还有一个额外的问题请您回答。我在跟踪 java 程序时遇到问题,我相信这是由于“java vm magic”。我用execlp("java", "java", "-jar", "hello.jar", NULL); 替换了execl,它基本上运行hello world 程序,但没有出现系统调用4。有什么线索吗?
    猜你喜欢
    • 1970-01-01
    • 2015-12-04
    • 2016-01-27
    • 1970-01-01
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多