为什么 clock() returns -1 在 C 中
Why does clock() returns -1 in C
我正在尝试使用 "time.h"
库中的 clock()
函数实现错误处理程序。嵌入式系统(Colibri IMX7 - M4 处理器)中的代码 运行s。该函数用于监视特定范围内的电流值,如果电流值不正确,该函数应该return 一个错误消息。
该函数将查看错误是否发生,在第一个 运行 中,它将第一次出现的错误保存在 clock_t
中作为参考,然后在下一个 [=33] 中=]s 如果错误仍然存在,它将使用 clock()
将当前时间与之前的参考进行比较,看看它是否会比特定时间长。
问题是函数 clock()
总是 returning -1。我应该怎么做才能避免这种情况?另外,为什么我不能将 clock_t
变量声明为静态变量(例如 static clock_t start_t = clock()
?
请看下面的功能:
bool CrossLink_check_error_LED_UV_current_clock(int current_state, int current_at_LED_UV)
{
bool has_LED_UV_current_deviated = false;
static int current_number_of_errors_Current_LED_CANNON = 0;
clock_t startTimeError = clock();
const int maximum_operational_current_when_on = 2000;
const int minimum_turned_on_LED_UV_current = 45;
if( (current_at_LED_UV > maximum_operational_current_when_on)
||(current_state!=STATE_EMITTING && (current_at_LED_UV > minimum_turned_on_LED_UV_current))
||(current_state==STATE_EMITTING && (current_at_LED_UV < minimum_turned_on_LED_UV_current)) ){
current_number_of_errors_Current_LED_CANNON++;
if(current_number_of_errors_Current_LED_CANNON > 1) {
if (clock() - startTimeError > 50000){ // 50ms
has_LED_UV_current_deviated = true;
PRINTF("current_at_LED_UV: %d", current_at_LED_UV);
if(current_state==STATE_EMITTING){
PRINTF(" at state emitting");
}
PRINTF("\n\r");
}
}else{
if(startTimeError == -1){
startTimeError = clock();
}
}
}else{
startTimeError = 0;
current_number_of_errors_Current_LED_CANNON = 0;
}
return has_LED_UV_current_deviated;
}
编辑:我之前忘了提到,但我们使用 GCC 9.3.1 arm-none-eabi 编译器和 CMake 来构建可执行文件。我们有一个嵌入式系统(由 Toradex 制造的 Colibri IMX7),由 2 个 A7 处理器组成,运行 是我们的 Linux(更直观的界面)和用于控制我们设备的程序 运行s 在没有 OS 的 M4 处理器中,只是纯裸机。
对于c标准库中提供的很多函数,如果安装了文档(通常是随编译器安装的),可以在[=22]中使用man
命令查看文档=].使用 man clock
,它告诉我:
NAME
clock - determine processor time
SYNOPSIS
#include <time.h>
clock_t clock(void);
DESCRIPTION
The clock() function returns an approximation of processor time used by the program.
RETURN VALUE
The value returned is the CPU time used so far as a clock_t; to get the number of seconds used, divide by
CLOCKS_PER_SEC. If the processor time used is not available or its value cannot be represented, the function
returns the value (clock_t) -1.
etc.
这告诉我们 -1 表示处理器时间 (CLOCK_PROCESS_CPUTIME_ID
) 不可用。解决方案是使用 CLOCK_MONOTONIC
代替。我们可以 select 我们想要使用的时钟 clock_gettime
.
timespec clock_time;
if (clock_gettime(CLOCK_MONOTONIC, &clock_time)) {
printf("CLOCK_MONOTONIC is unavailable!\n");
exit(1);
}
printf("Seconds: %d Nanoseconds: %ld\n", clock_time.tv_sec, clock_time.tv_nsec);
回答你问题的第二部分:
static clock_t start_time = clock();
是不允许的,因为函数 clock()
的 return 值直到运行时才知道,但在 C 中,静态变量的初始值设定项必须是 compile-time 常量。
你可以这样写:
static clock_t start_time = 0;
if (start_time == 0)
{
start_time = clock();
}
但这可能适合也可能不适合在这种情况下使用,具体取决于零是否是函数的合法 return 值。如果可以的话,你需要这样的东西:
static bool start_time_initialized = false;
static clock_t start_time;
if (!start_time_initialized)
{
start_time_initialized = true;
start_time = clock();
}
只有当你不能同时拥有这个函数运行的两个副本时,以上才是可靠的(它不是re-entrant)。
如果您有可用的 POSIX 库,您可以使用 pthread_once_t 来执行与上述 bool 相同的操作,但采用 re-entrant 方式。有关详细信息,请参阅 man pthread_once
。
请注意,C++ 允许在此区域中使用更复杂的选项,但您已经询问过 C。
另请注意,将“开始时间”缩写为 start_t
是一个非常糟糕的主意,因为后缀 _t
表示“类型”,只能用于类型名称。
最后的问题是,由于我们 运行 我们的代码是在裸机上运行的,所以 clock() 函数无法正常工作。我们最终在我们发现的 M4 处理器上使用了一个内部计时器,所以现在一切都很好。感谢您的回答。
我正在尝试使用 "time.h"
库中的 clock()
函数实现错误处理程序。嵌入式系统(Colibri IMX7 - M4 处理器)中的代码 运行s。该函数用于监视特定范围内的电流值,如果电流值不正确,该函数应该return 一个错误消息。
该函数将查看错误是否发生,在第一个 运行 中,它将第一次出现的错误保存在 clock_t
中作为参考,然后在下一个 [=33] 中=]s 如果错误仍然存在,它将使用 clock()
将当前时间与之前的参考进行比较,看看它是否会比特定时间长。
问题是函数 clock()
总是 returning -1。我应该怎么做才能避免这种情况?另外,为什么我不能将 clock_t
变量声明为静态变量(例如 static clock_t start_t = clock()
?
请看下面的功能:
bool CrossLink_check_error_LED_UV_current_clock(int current_state, int current_at_LED_UV)
{
bool has_LED_UV_current_deviated = false;
static int current_number_of_errors_Current_LED_CANNON = 0;
clock_t startTimeError = clock();
const int maximum_operational_current_when_on = 2000;
const int minimum_turned_on_LED_UV_current = 45;
if( (current_at_LED_UV > maximum_operational_current_when_on)
||(current_state!=STATE_EMITTING && (current_at_LED_UV > minimum_turned_on_LED_UV_current))
||(current_state==STATE_EMITTING && (current_at_LED_UV < minimum_turned_on_LED_UV_current)) ){
current_number_of_errors_Current_LED_CANNON++;
if(current_number_of_errors_Current_LED_CANNON > 1) {
if (clock() - startTimeError > 50000){ // 50ms
has_LED_UV_current_deviated = true;
PRINTF("current_at_LED_UV: %d", current_at_LED_UV);
if(current_state==STATE_EMITTING){
PRINTF(" at state emitting");
}
PRINTF("\n\r");
}
}else{
if(startTimeError == -1){
startTimeError = clock();
}
}
}else{
startTimeError = 0;
current_number_of_errors_Current_LED_CANNON = 0;
}
return has_LED_UV_current_deviated;
}
编辑:我之前忘了提到,但我们使用 GCC 9.3.1 arm-none-eabi 编译器和 CMake 来构建可执行文件。我们有一个嵌入式系统(由 Toradex 制造的 Colibri IMX7),由 2 个 A7 处理器组成,运行 是我们的 Linux(更直观的界面)和用于控制我们设备的程序 运行s 在没有 OS 的 M4 处理器中,只是纯裸机。
对于c标准库中提供的很多函数,如果安装了文档(通常是随编译器安装的),可以在[=22]中使用man
命令查看文档=].使用 man clock
,它告诉我:
NAME
clock - determine processor time
SYNOPSIS
#include <time.h>
clock_t clock(void);
DESCRIPTION
The clock() function returns an approximation of processor time used by the program.
RETURN VALUE
The value returned is the CPU time used so far as a clock_t; to get the number of seconds used, divide by
CLOCKS_PER_SEC. If the processor time used is not available or its value cannot be represented, the function
returns the value (clock_t) -1.
etc.
这告诉我们 -1 表示处理器时间 (CLOCK_PROCESS_CPUTIME_ID
) 不可用。解决方案是使用 CLOCK_MONOTONIC
代替。我们可以 select 我们想要使用的时钟 clock_gettime
.
timespec clock_time;
if (clock_gettime(CLOCK_MONOTONIC, &clock_time)) {
printf("CLOCK_MONOTONIC is unavailable!\n");
exit(1);
}
printf("Seconds: %d Nanoseconds: %ld\n", clock_time.tv_sec, clock_time.tv_nsec);
回答你问题的第二部分:
static clock_t start_time = clock();
是不允许的,因为函数 clock()
的 return 值直到运行时才知道,但在 C 中,静态变量的初始值设定项必须是 compile-time 常量。
你可以这样写:
static clock_t start_time = 0;
if (start_time == 0)
{
start_time = clock();
}
但这可能适合也可能不适合在这种情况下使用,具体取决于零是否是函数的合法 return 值。如果可以的话,你需要这样的东西:
static bool start_time_initialized = false;
static clock_t start_time;
if (!start_time_initialized)
{
start_time_initialized = true;
start_time = clock();
}
只有当你不能同时拥有这个函数运行的两个副本时,以上才是可靠的(它不是re-entrant)。
如果您有可用的 POSIX 库,您可以使用 pthread_once_t 来执行与上述 bool 相同的操作,但采用 re-entrant 方式。有关详细信息,请参阅 man pthread_once
。
请注意,C++ 允许在此区域中使用更复杂的选项,但您已经询问过 C。
另请注意,将“开始时间”缩写为 start_t
是一个非常糟糕的主意,因为后缀 _t
表示“类型”,只能用于类型名称。
最后的问题是,由于我们 运行 我们的代码是在裸机上运行的,所以 clock() 函数无法正常工作。我们最终在我们发现的 M4 处理器上使用了一个内部计时器,所以现在一切都很好。感谢您的回答。