我正在尝试如何在linux环境中使用c++中的getrusage函数,并且想知道我是否在正确的轨道上。
在申请项目之前,我编写了一个小程序,以确保我了解getrusage是如何工作的。我希望分别获得父进程和子进程的用户/内核时间。
void stupidFunction();
void childSort();
int main(void)
{
pid_t parent_pid=getpid();
struct rusage parent_before_function_usage;
getrusage(RUSAGE_SELF,&parent_before_function_usage);
time_t parent_before_function_user_usage_sec=parent_before_function_usage.ru_utime.tv_sec;
time_t parent_before_function_user_usage_microsec=parent_before_function_usage.ru_utime.tv_usec;
time_t parent_before_function_cpu_usage_sec =parent_before_function_usage.ru_stime.tv_sec;
time_t parent_before_function_cpu_usage_microsecsec =parent_before_function_usage.ru_stime.tv_usec;
stupidFunction();
pid_t pid;
if((pid = fork()) <0)
{
fprintf(stderr,"Failed to create a fork process\n");
}
else if (pid == 0)
{
childSort();
}
int status;
waitpid(-1,&status,0);
printf("in parent\n");
struct rusage parent_after_function_usage;
getrusage(RUSAGE_SELF,&parent_after_function_usage);
time_t parent_after_function_user_usage_sec=parent_after_function_usage.ru_utime.tv_sec;
time_t parent_after_function_user_usage_microsec=parent_after_function_usage.ru_utime.tv_usec;
time_t parent_after_function_cpu_usage_sec =parent_after_function_usage.ru_stime.tv_sec;
time_t parent_after_function_cpu_usage_microsecsec =parent_after_function_usage.ru_stime.tv_usec;
time_t parent_real_user_usage_sec=parent_after_function_user_usage_sec - parent_before_function_user_usage_sec;
time_t parent_real_user_usage_microsec= parent_after_function_user_usage_microsec - parent_before_function_user_usage_microsec;
time_t parent_real_cpu_usage_sec=parent_after_function_cpu_usage_sec - parent_before_function_cpu_usage_sec;
time_t parent_real_cpu_usage_microsec = parent_after_function_cpu_usage_microsecsec - parent_before_function_cpu_usage_microsecsec;
printf("User mode CPU time for parent: %d seconds, %d microseconds\n",parent_real_user_usage_sec,parent_real_user_usage_microsec);
printf("Kern mode CPU time for parent: %d seconds, %d microseconds\n",parent_real_cpu_usage_sec,parent_real_cpu_usage_microsec);
struct rusage child_function_usage;
getrusage(RUSAGE_CHILDREN,&child_function_usage);
time_t all_children_user_usage_sec=child_function_usage.ru_utime.tv_sec;
time_t all_children_user_usage_microsec=child_function_usage.ru_utime.tv_usec;
time_t all_children_cpu_usage_sec =child_function_usage.ru_stime.tv_sec;
time_t all_children_cpu_usage_microsec =child_function_usage.ru_stime.tv_usec;
printf("User mode CPU time for all children: %d seconds, %d microseconds\n",all_children_user_usage_sec,all_children_user_usage_microsec);
printf("Kern mode CPU time for all children: %d seconds, %d microseconds\n",all_children_cpu_usage_sec,all_children_cpu_usage_microsec);
return 0;
}
void stupidFunction()
{
int i=0;
while(i<900000000)
{
// printf("%d\n",i);
i+=1;
}
}
void childSort()
{
printf("in childSort\n");
int fd[2];
fd[0]=open("file1", O_RDONLY,0777);
fd[1]=open("file2", O_WRONLY,0777);
dup2(fd[0],0);
dup2(fd[1],1);
char* execArgs[2];
execArgs[0]="sort";
execArgs[1]=NULL;
execvp(execArgs[0],execArgs);
}请提供一些关于代码正确性的反馈,而且,如果不是一个孩子,我有很多,这个代码会返回所有孩子加在一起的用法吗?
发布于 2016-01-30 17:22:31
语义RUSAGE_CHILDREN在手册页中有很清楚的解释:
RUSAGE_CHILDREN 返回已终止并等待的调用进程的所有子进程的资源使用统计信息。这些统计数字将包括孙辈使用的资源,并进一步删除后代,前提是所有受干预的后代都等待被终止的子女。
由于您的子进程已经终止,并且您一直在等待它,因此它的统计信息应该包含在您的getrusage(RUSAGE_CHILDREN, ...)调用的数据中。如果你把电话放在waitpid之前,他们就不会被包括在内。
注意,它清楚地指出,这包括所有的孩子,即使有一个以上的孩子,以及更多的后代,只要他们已经被终止和等待。
我确实在你的程序中看到了一些错误,它们可以解释你可能看到的任何奇怪的行为。
首先,tv_usec成员的struct timeval类型不是time_t,而是suseconds_t。原则上,将.tv_usec分配给time_t类型的变量可能会使其溢出。
接下来,您的_sec和_microsec变量是time_t类型的,但是您可以使用%d格式说明符将它们打印到printf(),这是为int设计的。如果time_t的类型大于int (在64位Linux系统上就是这种情况),那么这是行不通的。当您将_microsec变量更改为正确类型的suseconds_t时,情况也是如此。
现在,我们不一定对time_t和suseconds_t的类型了解很多。POSIX只表示time_t可以是整数类型,也可以是浮点类型,而suseconds_t是一个有符号整数类型,可以表示0到1000000之间的数字。
在所有Linux平台上,据我所知,time_t是一个带符号的整数类型,所以我相信我们可以安全地完成。
time_t sec = ... ;
time_t microsec = ...;
printf("Time is %jd seconds and %jd microseconds\n", (intmax_t)sec, (intmax_t)microsec);这不一定是可移植到所有Unix系统,但我认为它将工作在其中的大多数。
此外,使用0777模式打开文件也是一种糟糕的做法,甚至对于测试来说也是如此。
https://stackoverflow.com/questions/35100805
复制相似问题