Linux多线程中如何获取线程时间?

内核编译和嵌入式产品的设计与开发
回复
chenxitwo
帖子: 31
注册时间: 2011-08-13 20:03

Linux多线程中如何获取线程时间?

#1

帖子 chenxitwo » 2015-05-21 11:51

Linux中利用gettimeofday()获取系统时间,再计算时间差值,将这个时间差值作为线程的运行时间是不准确的。因为Linux是多任务并行的。

举例来说系统同时在运行线程A,B,C。现在要计算线程A中某一任务的时间,在任务开始利用gettimeofday()函数获取时间,在任务结束时再利用gettimeofday()获取时间,将两个时间的差值就是任务的执行时间。但这个任务的花费的cpu时间比较长,在任务执行期间肯定会有线程调度发生,运行其他线程。这样导致计算得来的时间不准确(包括了其它线程执行的时间)。

在网上查了下,找到一个clock_gettime()函数,通过CLOCK_THREAD_CPUTIME_ID可以获取线程时间。
但疑惑的是这个函数是计算线程的cpu时间片,还是计算线程开始执行 和 执行当前代码(获取时间)的系统时间差值?假如是后者的话,则说明这个函数也不能满足要求。
头像
astolia
论坛版主
帖子: 6454
注册时间: 2008-09-18 13:11

Re: Linux多线程中如何获取线程时间?

#2

帖子 astolia » 2015-05-25 11:07

如果你觉得manpage上的说明比较模糊,你就不会自己写段代码实验一下吗?

代码: 全选

#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main() {
	struct timespec t1,t2;
	clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t1);
	sleep(1);
	clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t2);
	printf("%ld, %ld\n%ld, %ld\n", t1.tv_sec, t1.tv_nsec, t2.tv_sec, t2.tv_nsec);
	return 0;
}
chenxitwo
帖子: 31
注册时间: 2011-08-13 20:03

Re: Linux多线程中如何获取线程时间?

#3

帖子 chenxitwo » 2015-05-25 18:08

astolia 写了:如果你觉得manpage上的说明比较模糊,你就不会自己写段代码实验一下吗?
大哥,我是想快点得到结果,这个去验证比较麻烦。不是简单的一个线程就可以的,需要用多线程,还要考虑到多核问题。

最后已经验证了clock_gettime()函数是可以获取线程的cpu执行时间。

代码:

代码: 全选

#include <time.h>
void delayms(int n_msec)
{
   u_int32 i,j,k ;
   
   for(i=15*n_msec;i>0;i--)
     for(j=202;j>0;j--)
       for(k=81;k>0;k--);
}

void test1_task()
{
	u_int64 msec=0;
	struct timeval   time_start1, time_stop1;
	struct timespec   time_start, time_stop;
	gettimeofday(&time_start1, 0);
	clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time_start);

	delayms(10*1000);
	//sleep(10);

	gettimeofday(&time_stop1, 0);
	clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time_stop);

	msec = timevaldiff_2(&time_start, &time_stop);
	printf("msec=%lld\n", msec);
	msec = timevaldiff(&time_start1, &time_stop1);
	printf("msec=%lld\n", msec);
	
	return;
}

void test2_task()
{
	printf("test2_task start\n");
	{
		delayms(20*1000);
		
	}
	printf("test2_task stop\n");
	return ;
}


void test(void)
{
	THREAD_ID	test1_task_id;
	THREAD_ID	test2_task_id;
	THREAD_ID	test3_task_id;
	THREAD_ID	test4_task_id;
	THREAD_ID	test5_task_id;
	THREAD_ID	test6_task_id;
	THREAD_ID	test7_task_id;
	THREAD_ID	test8_task_id;
	THREAD_ID	test9_task_id;

	thread_create(test1_task, 0, (void **)NULL, 
		(u_int32)(1024*32), 127, "test1_task", &test1_task_id);

	thread_create(test2_task, 0, (void **)NULL, 
		(u_int32)(1024*32), 127, "test2_task", &test2_task_id);
	thread_create(test2_task, 0, (void **)NULL, 
		(u_int32)(1024*32), 127, "test3_task", &test3_task_id);
	thread_create(test2_task, 0, (void **)NULL, 
		(u_int32)(1024*32), 127, "test4_task", &test4_task_id);
	thread_create(test2_task, 0, (void **)NULL, 
		(u_int32)(1024*32), 127, "test5_task", &test5_task_id);
	thread_create(test2_task, 0, (void **)NULL, 
		(u_int32)(1024*32), 127, "test6_task", &test6_task_id);
	thread_create(test2_task, 0, (void **)NULL, 
		(u_int32)(1024*32), 127, "test7_task", &test7_task_id);
	thread_create(test2_task, 0, (void **)NULL, 
		(u_int32)(1024*32), 127, "test8_task", &test8_task_id);
	
}
这个是在双核cpu上运行,运行结果:
test2_task start
test2_task start
test2_task start
test2_task start
test2_task start
test2_task start
test2_task start
msec=11246
msec=45496
test2_task stop
test2_task stop
test2_task stop
test2_task stop
test2_task stop
test2_task stop
test2_task stop
头像
astolia
论坛版主
帖子: 6454
注册时间: 2008-09-18 13:11

Re: Linux多线程中如何获取线程时间?

#4

帖子 astolia » 2015-05-25 23:30

说白了就是你根本不懂内核的线程调度机制,sleep的原理估计也不清楚,否则哪要考虑那么多
回复