我有一个特殊的功能(好吧,一组功能),我想每400ms启动一次。我不是一个C程序员,因此标准库之外的任何东西对我来说都是一个谜,而且在我们内部也是如此。
我的第一个想法是使用nanosleep在某种循环中暂停执行400ms,但这当然没有考虑我将运行的代码的执行时间。如果我可以测量它,并且如果它看起来相当确定它在10或20次测试后运行相同的大致持续时间,那么我可以使用nanosleep()来获得差异。当然,这不是完美的......但它可能足够接近第一次尝试。
如何衡量C函数的执行时间?或者是否有更好的方法来完成这项工作,我需要使用哪些关键字进行Google搜索?
答案 0 :(得分:4)
您应该可以使用settimer
int setitimer(int which, const struct itimerval *value,
struct itimerval *ovalue);
只需将您想要在SIGALRM处理程序中每400ms执行一次的代码。这样,您无需考虑代码运行所需的时间,这可能会有所不同。我不确定如果在生成下一个信号之前信号处理程序没有返回会发生什么。
下面显示了一些代码可能的样子。
void periodic_fuc(int signal_num)
{
...
signam(SIGALRM, periodic_func);
}
int main(...)
{
struct itimerval timerval = {0};
signal(SIGALRM, periodic_func);
...
timerval.it_interval.tv_usec = 400000;
timerval.it_value.tv_usec = 400000; // Wait 400ms for first trigger
settimer(ITIMER_REAL, &timerval, NULL);
while (!exit)
sleep(1);
return 0;
}
答案 1 :(得分:1)
看看gprof。它允许您快速重新编译代码并生成有关正在调用哪些函数以及占用程序最多时间的信息。
答案 2 :(得分:1)
我同意torak关于使用setitimer()
的问题。但是,由于不清楚当SIGALRM
处理程序退出时是否重新启动间隔,并且你真的不应该在信号处理程序中做很多工作,所以最好只有它设置了一个标志,并在主程序中完成工作:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
volatile sig_atomic_t wakeup = 0;
void alarm_handler(int signal_num)
{
wakeup = 1;
}
int main()
{
struct itimerval timerval = { 0 };
struct sigaction sigact = { 0 };
int finished = 0;
timerval.it_interval.tv_usec = 400000;
timerval.it_value.tv_usec = 400000;
sigact.sa_handler = alarm_handler;
sigaction(SIGALRM, &sigact, NULL);
setitimer(ITIMER_REAL, &timerval, NULL);
while (!finished)
{
/* Wait for alarm wakeup */
while (!wakeup)
pause();
wakeup = 0;
/* Code here... */
printf("(Wakeup)\n");
}
return 0;
}
答案 3 :(得分:0)
您可以在函数之前和之后使用gettimeofday()
或clock_gettime()
来计算时间,然后计算两次之间的差值。
答案 4 :(得分:0)
对于Linux,您可以使用gettimeofday。在函数开头调用gettimeofday。运行你必须运行的任何东西。然后得到结束时间并弄清楚你需要多长时间睡觉。然后将usleep调用适当的微秒数。
答案 5 :(得分:0)
查看POSIX计时器。这是some documentation at HP。
你可以使用与setitimer相同的功能,但你也可以使用timer_getoverrun()来告诉你在你的功能中是否错过了任何计时器事件。