我的C程序可以运行超过3个小时。为了我的实验,我想计算程序所用的持续时间(即执行时间),直到完成为止。我在start = clock();
的开头使用main()
,最后我end = clock()
,最后减去end - start
获取执行时间。但是,正如here所述,clock_t clock(void)
限制为72分钟。我怎样才能强制执行它来计算整个执行时间不仅仅是72分钟?
答案 0 :(得分:2)
使用gettimeofday()
(https://linux.die.net/man/2/gettimeofday)。它在很长一段时间内提供微秒分辨率。记录开始时间和结束时间并计算差异。
答案 1 :(得分:2)
time()
函数在C89,C99,C11中指定。它具有第二个分辨率,通常超过30位秒。它可能是最便携的解决方案。事实上,直到今天我才听说过clock()
。即使你需要高分辨率,计数滴答也很少你想要的。
如果您不需要便携方式来测量CPU /执行时间,请使用procfs
。 proc/self/stat
的{{1}}字段和stime
应该就是您所需要的。
答案 2 :(得分:2)
所有POSIXy系统(包括Linux)的标准是clock_gettime() POSIX.1函数。
考虑以下示例:
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <time.h>
/* Clock used by wall_start()/wall_elapsed() */
#ifdef CLOCK_MONOTONIC
#define WALL_CLOCK_ID CLOCK_MONOTONIC
#else
#define WALL_CLOCK_ID CLOCK_REALTIME
#endif
static struct timespec wall_started = { 0 };
static inline void wall_start(void)
{
if (clock_gettime(WALL_CLOCK_ID, &wall_started)) {
wall_started.tv_sec = 0;
wall_started.tv_nsec = 0;
}
}
static inline void wall_elapsed(void)
{
struct timespec t;
if (!clock_gettime(WALL_CLOCK_ID, &t))
return (double)(t.tv_sec - wall_started.tv_sec)
+ (double)(t.tv_nsec - wall_started.tv_nsec) / 1000000000.0;
else
return -1.0;
}
/* Return the number of seconds of CPU time
used by this process (includes all threads)
*/
static inline double cpu_elapsed(void)
{
struct timespec t;
if (!clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t))
return (double)t.tv_sec
+ (double)t.tv_nsec / 1000000000.0;
return -1.0;
}
如果您想以天,小时,分钟和秒显示时间,您还需要一个简单的功能将(浮点)秒分为几天,几小时和几分钟。
这是一个实现,它指向int的天,小时和分钟;如果你不想将其拆分,你可以使用NULL。该函数返回剩余的秒数:
static inline double split_seconds(double secs,
int *days,
int *hours,
int *minutes)
{
/* We split the absolute number of seconds, only. */
if (secs < 0.0)
secs = 0.0;
if (days) {
const int ndays = (int)(secs / 86400.0);
secs -= (double)ndays * 86400.0;
*days = ndays;
}
if (hours) {
const int nhours = (int)(secs / 3600.0);
secs -= (double)nhours * 3600.0;
*hours = nhours;
}
if (minutes) {
const int nminutes = (int)(secs / 60.0);
secs -= (double)nminutes * 60.0;
*minutes = nminutes;
}
return secs;
}
例如,调用split_seconds(3661.25, NULL, &h, NULL)
会使61.25
返回h == 1
。致电split_seconds(3661.25, &d, &h, &m)
返回1.25
,d == 0
,h == 1
,m == 1
,对应0天,1小时,1分钟和1.25秒。
CLOCK_REALTIME
时钟是POSIXy系统中的标准挂钟,但它受NTP(网络时间协议)更改的影响,系统管理员可以直接设置它。但是,它不受夏令时或任何与时区相关的影响,因为它是UTC,而不是当地时间。
CLOCK_MONOTONIC
时钟类似于CLOCK_REALTIME
,但其时代未知(可能设置为机器上次启动时的某个时间),并且不受NTP时间跳转的影响(但受NTP的小增量更改影响,以使计算机时钟与网络时间源保持同步),并且不受系统管理员对系统时间更改的影响。
如果可用,CLOCK_MONOTONIC
被认为比CLOCK_REALTIME
更适合衡量过去的实际时间; CLOCK_REALTIME
更适合与绝对现实世界时间进行比较的情况,或者检查特定日期/时间是否已经过去。
如果您打算将时间戳存储到例如一个文件,你必须使用CLOCK_REALTIME
而不是CLOCK_MONOTONIC
,因为后者只在同一台机器上有意义,直到下一次启动。
使用CLOCK_REALTIME
时,请记住它是UTC格式,用户通常会在当地时间指定时间和日期;您可能希望使用strptime()
POSIX.1函数来解析文本(在Linux中使用#define _XOPEN_SOURCE
),并使用mktime()
生成可以存储到{time_t
的{{1}} 1}} tv_sec
结构的成员。