一个进程如何查询,何时启动?

时间:2014-10-15 20:02:30

标签: c unix freebsd system-calls bsd

当前进程开始时,是否有可用于询问操作系统的调用?

当然,人们可以在启动时简单地调用gettimeofday(),并在整个过程的生命周期中引用一次记录的值,但还有其他选择吗?

显然,操作系统会保留每个进程的记录(例如,可以在ps的输出中看到它)。过程本身是否可以查询(使用C)?

理想的解决方案当然是跨平台的,但某些(免费)BSD特定的也是如此。谢谢!

更新:我已经提出了一个特定于BSD的实现,它使用sysctl(3)来获取当前进程的kern_proc结构,并在那里找到ki_start字段。如果没有人在几天内提出更好的建议,我会在这里发布我自己的功能以供后人使用......

3 个答案:

答案 0 :(得分:1)

您可以查看/proc/[process-id]文件夹..在其上执行fstat()以获取更多信息..

答案 1 :(得分:1)

好的,这是我自己的功能 - 它适用于FreeBSD,很可能适用于Open,Net和DragonFly BSD。也许,在MacOS上也是如此。随意采取并调整品味 - 该函数将值缓存在静态变量中,这意味着,如果您的过程在函数调用之后调用一次,则子项将具有父值。另外,我丢弃timeval的微秒部分,但您可能需要它。

static void
getstarttime(struct timeval *ptv)
{
    static time_t   start; /* We cache this value */
    int             mib[4];
    size_t          len;
    struct kinfo_proc   kp;

    ptv->tv_usec = 0;   /* Not using microseconds at all */

    if (start != 0) {
        ptv->tv_sec = start;
        return;
    }
    ptv->tv_sec = 0;

    len = 4;
    if (sysctlnametomib("kern.proc.pid", mib, &len) != 0) {
        warn("Unable to obtain script start-time: %s",
            "sysctlnametomib");
        return;
    }
    mib[3] = getpid();
    len = sizeof(kp);
    if (sysctl(mib, 4, &kp, &len, NULL, 0) != 0) {
        warn("Unable to obtain script start-time: %s",
            "sysctl");
        return;
    }

    start = ptv->tv_sec = kp.ki_start.tv_sec;
}

答案 2 :(得分:1)

不确定这是否适用于FreeBSD以外的BSD(仅在FreeBSD 10.0,amd64上测试)。花了很多东西来分离源代码ps,除了使用系统库之外,它还做了Mikhail T.解决方案所做的事情。虽然尽管如此,但是代码非常粗糙(因为“它确实不应该那么难,对吧?”因为“它确实不应该那么难,对吧?”,而且2个多小时之后,这就是我所拥有的。非常有效。

请记住使用-lkvm标志进行编译以引入libkvm(内核数据库)。 kinfo_proc在/usr/include/sys/user.h中有详细说明,并且您希望了解有关进程的一些信息。下面的示例代码使用当前进程,但它只是根据PID提取信息。我已经在我的废品代码中找到了你需要提取流程的环境变量和其他东西,只需告诉我你是否需要。

#include <fcntl.h>
#include <kvm.h>
#include <sys/sysctl.h>
#include <sys/user.h>


#include <unistd.h>
#include <stdio.h>
#include <time.h>

int main(int argc,char** args) {
    kvm_t* kd;

    // Get a handle to libkvm interface
    kd = kvm_open(NULL, "/dev/null", NULL, O_RDONLY, "error: ");

    pid_t pid;
    pid = getpid();

    struct kinfo_proc * kp;
    int p_count;

    // Get the kinfo_proc for this process by its pid
    kp = kvm_getprocs(kd, KERN_PROC_PID, pid, &p_count);

    printf("got %i kinfo_proc for pid %i\n", p_count, pid);

    time_t proc_start_time;
    proc_start_time = kp->ki_start.tv_sec;
    kvm_close(kd);

    printf("Process started at %s\n", ctime(&proc_start_time));
    return 0;
}

修改

完整的源代码,例如包括FreeBSD,NetBSD和Mac OS X(当我有机会时可以使用OpenBSD)可以在这里找到:https://github.com/dnabre/misc/tree/master/proc_info