【问题标题】:struct tms values returned by times() all zero or negativetimes() 返回的 struct tms 值全部为零或负数
【发布时间】:2011-12-18 06:15:52
【问题描述】:

我正在尝试在 C 编程中实现 times() 函数。

我正在使用由以下字段组成的struct tms 结构:tms_utime、tms_cutime、 tms_stime 和 tms_cstime。

为了在我的程序中实现 times() 函数,我这样做了:

  1. 在我 fork 并创建一个子进程之前,我调用了 times 函数(在父进程中)。

    times(&start_tms);
    
  2. 我创建了一个管道,当我在子进程中时,我将启动结构的时间传递给管道。
  3. 孩子执行一个简单的ls -l 命令
  4. 当孩子完成他的执行时,父亲第二次调用 times() 函数。

    times(&end_tms);
    

    很遗憾,end_tms 的时间都是零!奇怪,但我不知道为什么。

在我的程序中我不明白的一些事情是:

1) 在第一个printfs 中,struct start 的时间为负数。这是为什么? 2)当我运行程序时,为什么我得到零次?我做错了什么?

我的程序如下:

谢谢,提前


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

int main() {

printf("test\n");

int     fd[2]; //two pointers
int nbytes;
char    string[] = "Hello, world!\n";
char    readbuffer[80];
struct tms start_tms;
struct tms end_tms;
clock_t start, end;
double cpu_time_used;

pipe(fd);

//once we have established the pipeline we fork the child
pid_t   childpid;
pid_t pid_waitpid;

//NEW MODIFICATION!!! call times before fork()!!!
times(&start_tms);

//they return negative values, but why???
printf("Test start_tms.tms_utime = %f\n\n",start_tms.tms_utime);
printf("Test start_tms.tms_cutime = %f\n\n",start_tms.tms_cutime);
printf("Test start_tms.tms_stime = %f\n\n",start_tms.tms_stime);


if((childpid = fork()) == -1)
            {
                    perror("fork");
                    exit(1);
            }

if(childpid == 0)
            {

                    /* Child process closes up input side of pipe */
                     close(fd[0]);

                   /* call times function */ 
                   /*times(&start_tms);*/


                      //REMOVED!!!!
                    //write(fd[1], string, (strlen(string)+1));
                    write(fd[1], &start_tms.tms_cutime, sizeof(clock_t));
                    write(fd[1], &start_tms.tms_utime, sizeof(clock_t));
                    write(fd[1], &start_tms.tms_stime, sizeof(clock_t));

                     //execute /bin/ls
                    execl("/bin/ls", "/bin/ls", "-r", "-t", "-l", (char *) 0);

                    exit(0);


            }
else
            {
                    /* Parent process closes up output side of pipe */
                    close(fd[1]);

                    /* NEW MODIFICATION, wait for the child!!! */
                     if( (pid_waitpid  = waitpid(childpid,NULL,0) ) == -1)
                    {
                             perror("waitpid");
                             exit(1);
                     }



                    /* call times for capturing end times */
                    times(&end_tms);

                    /* define t1, t2, variables */
                    clock_t t1,t2,t3;


                     //REMOVED!!!!
                    //nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
                    read(fd[0], &t1, sizeof(clock_t));
                    read(fd[0], &t2, sizeof(clock_t));
                    read(fd[0], &t3, sizeof(clock_t));

                    printf("Received string: %s\n\n", readbuffer);
                    printf("Test t1 = %f\n\n",t1);
                    printf("Test end_tms.tms_utime = %f\n\n",end_tms.tms_utime);
                    printf("Test end_tms.tms_cutime = %f\n\n",end_tms.tms_cutime);
                    printf("Test end_tms.tms_stime = %f\n\n",end_tms.tms_stime);

                    /* Calculate times, unfortunately return zero, but why??? */
                    double cpu_time = end_tms.tms_cutime - t1;
                    double utime = end_tms.tms_utime - t2;
                    double stime = end_tms.tms_stime - t3;

                    //Unfortunately printfs return zero, but why???
                    printf("cpu time %f\n\n",cpu_time);
                    printf("cpu Utime %f\n\n",utime);
                    printf("cpu Stime %f\n\n",stime);


}

}

【问题讨论】:

  • “实现”意味着您是为 times() 函数编写代码的人,而您并没有这样做——这是您正在调用的库函数。你可以说你在“调用”或“使用”它,但你并没有实现它。
  • 是的,你是对的,对不起...我使用它是为了在 struct tms 中捕获时间

标签: c struct tms


【解决方案1】:

你的逻辑很奇怪。您在子级中所做的写入只是复制start_tms 中父级已经可用的数据,因此您的整个管道读/写操作是不必要的。

其次,clock_t 不是浮点类型,而是整数类型。您不能使用%f 来打印它。在printfs 中使用%jdintmax_t 是安全的。

而您缺少 #include &lt;sys/wait.h&gt; 的 waitpid。所以打开你的编译器警告,并阅读它们。

这是您的代码的 C99 版本,可在此处使用:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/wait.h>
#include <sys/times.h>
#include <sys/types.h>

int main() {
    struct tms start_tms;
    struct tms end_tms;

    //once we have established the pipeline we fork the child
    pid_t   childpid;

    times(&start_tms);

    printf("Test start_tms.tms_utime = %jd\n\n",  (intmax_t)start_tms.tms_utime);
    printf("Test start_tms.tms_cutime = %jd\n\n", (intmax_t)start_tms.tms_cutime);
    printf("Test start_tms.tms_stime = %jd\n\n",  (intmax_t)start_tms.tms_stime);
    printf("Test start_tms.tms_cstime = %jd\n\n",  (intmax_t)start_tms.tms_cstime);


    if((childpid = fork()) == -1)
    {
        perror("fork");
        exit(1);
    }

    if(childpid == 0)
    {
        //execute /bin/ls
        execl("/bin/ls", "/bin/ls", "-R", "-t", "-l", (char *) 0);
        exit(0);
    }
    else
    {
        /* Parent process */

        /* NEW MODIFICATION, wait for the child!!! */
        if (waitpid(childpid,NULL,0) == -1)
        {
            perror("waitpid");
            exit(1);
        }

        /* call times for capturing end times */
        times(&end_tms);

        printf("Test end_tms.tms_utime = %jd\n\n",end_tms.tms_utime);
        printf("Test end_tms.tms_cutime = %jd\n\n",end_tms.tms_cutime);
        printf("Test end_tms.tms_stime = %jd\n\n",end_tms.tms_stime);
        printf("Test end_tms.tms_cstime = %jd\n\n",end_tms.tms_cstime);

        /* Calculate times, unfortunately return zero, but why??? */
        clock_t cpu_time = end_tms.tms_cutime - start_tms.tms_cutime;
        clock_t utime = end_tms.tms_utime - start_tms.tms_utime;
        clock_t stime = end_tms.tms_stime - start_tms.tms_stime;
        clock_t cstime = end_tms.tms_cstime - start_tms.tms_cstime;

        //Unfortunately printfs return zero, but why???
        printf("cpu time %jd\n\n",  (intmax_t)cpu_time);
        printf("cpu Utime %jd\n\n", (intmax_t)utime);
        printf("cpu Stime %jd\n\n", (intmax_t)stime);
        printf("cpu CStime %jd\n\n", (intmax_t)cstime);
    }
}

如果您没有intmax_t,请检查您的实现中clock_t 的大小并找到与之匹配的标准整数类型,并在您的printf 调用中使用适当的格式字符串。

【讨论】:

  • 非常感谢您的回复!当您说“您的代码的 C99 版本...”时,那个 c99 版本是什么?另外,我将它复制并粘贴到我的系统中,但我仍然得到零。你也得到零吗??谢谢,提前。正如我所看到的,最后一个“printfs”只返回零 (0) 而不是 0.0000
  • C99 是 C 的最新版本。一些编译器不支持它的一部分,但现在应该没问题。如果ls 需要足够的时间(大目录),我不会得到 0。正如我在答案中所说,clock_t 不是浮点数,它是整数类型(仅限整数)。如果您想要几分之一秒,则需要将 clock_t 值除以 CLOCKS_PER_SEC 并将其存储为双精度(并使用 %f 格式字符串)。
  • (@programmer:还有,别再用多个问号了???????一个就够了。多了会让你看起来很笨。)
  • 感谢您的回复。好吧,当我为“ls”执行程序 ./a.out 时,它返回大约 268 个文件,并且所有时间都返回零。此外,我在命令行中键入“times /bin/ls”,然后返回的 unix 命令这 268 个文件的以下时间不为零(0m0.172s 0m0.028s 0m5.912s 0m0.816s)。因此,我的程序将返回非零值。但我无法理解为什么它不返回非零值时间。你相信如果目录包含更多文件,我会收到非零时间值吗?
  • 将您的exec 替换为time_t t = time(NULL) + 5; while (t != time(NULL)) {};。这将在孩子中忙碌循环约 5 秒。如果您仍然得到 0 值,则说明有问题。 (它在这里报告了正确的数字。)
猜你喜欢
  • 1970-01-01
  • 2019-09-03
  • 2012-03-22
  • 2020-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多