一个跟踪 CPU 时间和内存使用情况的 Linux shell

发布于 2024-10-20 04:42:18 字数 646 浏览 6 评论 0原文

我正在尝试做的事情的简短概要:

模拟一个 shell 程序,当用户在自己的进程中输入命令时执行命令,并且在每个进程完成后,输出所有子进程和 shell 在该进程上花费的总时间CPU,以及单个进程已使用的最大内存量。

创建 shell 并执行命令不是问题,但跟踪进程的统计信息却让我陷入困境。

为了跟踪 CPU 时间,我将使用 time 系统调用并将用户的命令通过 shell 传递到 time 中,以便进程可以完成运行,并且在执行结束时我将获得可用的 time 信息。但是,当涉及到获取 shell(当前程序)在 CPU 上花费的时间时,我不完全确定该怎么做,因为我见过或遇到的每个时间实现都使用上述传递时间的方法命令和参数进入时间,但我无法使用 shell 做到这一点。我目前唯一的想法是让 shell 也成为一个子进程,运行一段时间,当 shell 完成运行子进程时,重新启动 shell,从 time 中提取信息,然后重新启动 shell。这看起来很绕,但我找不到任何系统调用来执行我想要的操作。

至于内存使用情况,本来想用top,然后把信息拉出来,但是iirc top只监控当前内存使用情况,而不是总量。我唯一能想到的另一件事就是进入 /proc// 并尝试从那里的某个地方提取信息。这又显得非常迂回。

任何朝着正确方向的推动都会很棒。所有这些都是用 C 语言完成的,如果这有什么不同的话。

A short synopsis of what I'm trying to do:

Emulate a shell program that executes commands as the user enters them in its own process, and after each process finished, output the total time that all child processes and the shell have spent on the CPU, and the max amount of memory that a single process has used.

Creating the shell and executing the commands isn't a problem, but when it comes to keeping track of the statistics about the processes is what has me stuck.

For keeping track of the CPU time, I was going to use the time system call and pass the user's command through the shell and into time so the process could finish running and at the end of execution I would have the information from time available to me. But when it comes to getting the time that the shell (current program) has spent on the CPU, I'm not entirely sure what to do because every implementation of time that I've seen or come across uses the above method of passing the commands and arguments into time, and I can't do that with the shell. The only idea I ahve at the moment is to make the shell a child process as well, run that through time, and when the shell finishes running a child process, reboot the shell, pull the information from time, and reboot the shell. Which seems very round about, but I can't find any system calls to do what I want.

As for the memory usage, I was thinking about using top and then pulling the information out, but iirc top only monitors current memory usage, not total. The only other thing I could think of would be going into /proc// and trying to pull the information out from somewhere in there. Which again, seems very roundabout.

Any nudge in the right direction would be awesome. All of this is done in C, if that makes a difference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

他不在意 2024-10-27 04:42:18

一种可能的方法是将每个用户命令作为单独的进程运行,并在进程完成时获取资源使用信息。好的,将命令作为进程运行非常简单(请参阅 fork() 和 exec* 系列)。资源使用情况(时间、内存等)怎么样?我建议看一下 getrusage() 系统调用。

男人说:

getrusage() 函数应
提供所用资源的衡量标准

当前进程或其终止并等待的子进程
流程。如果值
who 参数是 RUSAGE_SELF,信息应为
返回约
当前进程使用的资源。如果值
谁的论据是谁
RUSAGE_CHILDREN,应返回有关所使用资源的信息

终止并等待当前进程的子进程。

让我们看看这个系统调用提供了哪些信息:

struct rusage {
    struct timeval ru_utime; /* user time used */
    struct timeval ru_stime; /* system time used */
    long   ru_maxrss;        /* maximum resident set size */
    long   ru_ixrss;         /* integral shared memory size */
    long   ru_idrss;         /* integral unshared data size */
    long   ru_isrss;         /* integral unshared stack size */
    long   ru_minflt;        /* page reclaims */
    long   ru_majflt;        /* page faults */
    long   ru_nswap;         /* swaps */
    long   ru_inblock;       /* block input operations */
    long   ru_oublock;       /* block output operations */
    long   ru_msgsnd;        /* messages sent */
    long   ru_msgrcv;        /* messages received */
    long   ru_nsignals;      /* signals received */
    long   ru_nvcsw;         /* voluntary context switches */
    long   ru_nivcsw;        /* involuntary context switches */
};

我认为这足以解决您的问题。

One possible way is to run every user command as a separate process and when process finishes grab the resources usage information. Ok, running command as process is easy enough (see fork() and exec* family). What about resource usage (time, memory, etc)? I suggest take a look at getrusage() syscall.

man says:

The getrusage() function shall
provide measures of the resources used
by the
current process or its terminated and waited-for child
processes. If the value of
the who argument is RUSAGE_SELF, information shall be
returned about
resources used by the current process. If the value of the
who argument is
RUSAGE_CHILDREN, information shall be returned about resources used
by the
terminated and waited-for children of the current process.

Lets see what information this syscall provides:

struct rusage {
    struct timeval ru_utime; /* user time used */
    struct timeval ru_stime; /* system time used */
    long   ru_maxrss;        /* maximum resident set size */
    long   ru_ixrss;         /* integral shared memory size */
    long   ru_idrss;         /* integral unshared data size */
    long   ru_isrss;         /* integral unshared stack size */
    long   ru_minflt;        /* page reclaims */
    long   ru_majflt;        /* page faults */
    long   ru_nswap;         /* swaps */
    long   ru_inblock;       /* block input operations */
    long   ru_oublock;       /* block output operations */
    long   ru_msgsnd;        /* messages sent */
    long   ru_msgrcv;        /* messages received */
    long   ru_nsignals;      /* signals received */
    long   ru_nvcsw;         /* voluntary context switches */
    long   ru_nivcsw;        /* involuntary context switches */
};

I think this would be enough to solve your problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文