如何计算C语言中fork()系统调用的运行时间?

6

我正在尝试寻找fork()系统调用的运行时间。每个子进程需要立即退出,父进程需要在创建下一个子进程之前wait()每个子进程。我还想使用名为time的shell内置命令来测量程序的执行时间。

到目前为止,我有这段代码,但不确定我是否做得对。

#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int global = 100;

int main(int argc, char** argv)
{
    int local = 5;

    pid_t pid;

    pid = fork();
    if (pid < 0) {
        fprintf(stderr, "error -- failed to fork()");
        return 1;
    }

    if (pid > 0) {

        int child_ret;

        waitpid(pid, &child_ret, 0);
        printf("parent -- global: %i, local: %i\n", global, local);
        printf("parent -- child exited with code %i\n", child_ret);
    } else {
        global++;
        local++;

        printf("child -- global: %i, local: %i\n", global, local);
        exit (0);
    }
}

2
看一下 getrusage 系统调用。 - Kaz
代码能否正常运行?如果可以,您应该在codereview.stackexchange.com上发布。如果代码无法正常运行,请详细说明您认为的原因:您观察到了什么错误或意外行为? - David Grayson
你可能感到困惑,因为localglobal对于你的父进程没有改变,但是你的代码看起来是正确的。 - tkausl
1
你不应该在子进程中调用exit,而应该调用_exit。如果你在子进程中调用exit,它会运行父进程的“退出时”处理器,并且重复运行退出处理器的结果是不可预测的。这在过去曾经导致了严重的安全漏洞,因此不要养成管理进程不当的习惯。 - David Schwartz
1个回答

2
首先阅读time(7),考虑使用clock_gettime(2)getrusage(2);如果只想测量fork(2)系统调用本身的时间(非常短,可能只有一毫秒左右,并不重要),则可以在父进程中使用clock_gettime()来包围fork。在失败情况下,使用errno(例如打印strerror(errno)或使用perror)。
请注意,fork 的时间可能会略微取决于您的虚拟地址空间常驻集大小的大小。您也可以使用 strace 的计时功能;在实践中,fork 足够快(通常少于一毫秒,有时只有几十微秒;因为它使用延迟写时复制技术)。
所以 fork 很快,子进程的 execve 可能需要更多的微秒,子进程中程序启动时间也很重要(ld-linux(8) 在你执行的 exec 程序的 main 开始之前进行了一些 重定位...)。你想要测量什么? 通常情况下,子进程会快速调用 execve(2),这也需要一些时间(当然,被执行的程序可能需要任意长的时间来完成,如果它像服务器一样,甚至可能永远不会完成)。也许重要的是在子进程中,在 fork 之前和 execvemain 中的第一个有意义的指令之间的时间...
实际上,您可以启动许多进程;一个经验法则是每秒最多 fork 几百次,只有在子进程 快速 执行一些 快速 的程序(如几十个文件的 /bin/lsdate)时才这样做。然而,在笔记本电脑或台式机上,您不希望同时运行超过十几个可运行进程,甚至可能少于 5 个可运行进程...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接