首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C等低级语言高效重复闹钟

问用C等低级语言高效重复闹钟
EN

Software Engineering用户
提问于 2016-01-23 16:23:03
回答 2查看 1.6K关注 0票数 1

我在考虑这个问题,我很好奇如何用C语言编写一个高效的重复闹钟?你是否会设定一个警报时间,然后用相当于一天(或两天或一周)的毫秒时间来抵消这个时间,这取决于它需要重复的频率。然后定期投票看看时间是否平等?至少对我来说,这听起来是一个非常低效的解决方案。我对闹钟如何按程序工作感兴趣。

EN

回答 2

Software Engineering用户

发布于 2016-01-23 16:58:14

要做到这一点,有很多种方法,这都取决于您所使用的环境。另一个问题当然是你能负担得起的延迟。

如果您正在开发一个现代操作系统,那么您很可能有一个API,它会使线程处于休眠状态,直到给定的时间到来为止。Posix具有nanosleep(),C11具有执行此操作的thread_sleep()函数。

如果您使用更原始的操作系统或直接为嵌入式硬件编程,您可能不得不等待周期性中断,甚至使用繁忙的循环。

Update:要使用thread_sleep()方法处理多个警报,您可以将所有即将发出的警报存储在一个排序列表中。睡觉,直到第一次警报触发,做你应该做的,然后计算时间,直到下一个警报,然后回去睡觉。这种方法只使用一个计时器线程,只要它满足延迟需求,就会非常有效。

票数 4
EN

Software Engineering用户

发布于 2016-01-25 02:53:59

一个重复的计时器。

使用setitimer()

这是手册页上的信息

代码语言:javascript
复制
    NAME
           getitimer, setitimer - get or set value of an interval timer

    SYNOPSIS
           #include <sys/time.h>

           int getitimer(int which, struct itimerval *curr_value);
           int setitimer(int which, const struct itimerval *new_value,
                         struct itimerval *old_value);

    DESCRIPTION
           The  system  provides  each  process  with  three interval timers, each
           decrementing in a distinct time domain.  *When any timer expires, a sig‐
           nal is sent to the process*, and the timer (potentially) restarts.

           ITIMER_REAL    decrements in real time, and delivers SIGALRM upon expi‐
                          ration.

           ITIMER_VIRTUAL decrements only  when  the  process  is  executing,  and
                          delivers SIGVTALRM upon expiration.

           ITIMER_PROF    decrements  both  when the process executes and when the
                          system is executing on behalf of the  process.   Coupled
                          with  ITIMER_VIRTUAL, this timer is usually used to pro‐
                          file the time spent by the application in user and  ker‐
                          nel space.  SIGPROF is delivered upon expiration.

           Timer values are defined by the following structures:

               struct itimerval {
                   struct timeval it_interval; /* next value */
                   struct timeval it_value;    /* current value */
               };

               struct timeval {
                   time_t      tv_sec;         /* seconds */
                   suseconds_t tv_usec;        /* microseconds */
               };

           The  function  getitimer() fills the structure pointed to by curr_value
           with the current setting for the  timer  specified  by  which  (one  of
           ITIMER_REAL,  ITIMER_VIRTUAL, or ITIMER_PROF).  The element it_value is
           set to the amount of time remaining on the timer, or zero if the  timer
           is disabled.  Similarly, it_interval is set to the reset value.

           The  function  setitimer()  sets  the  specified  timer to the value in
           new_value.  If old_value is non-NULL, the old value  of  the  timer  is
           stored there.

           Timers decrement from it_value to zero, generate a signal, and reset to
           it_interval.  A timer which is set to zero (it_value  is  zero  or  the
           timer expires and it_interval is zero) stops.

           Both  tv_sec and tv_usec are significant in determining the duration of
           a timer.

           Timers will never expire before the requested time, but may expire some
           (short)  time  afterward,  which depends on the system timer resolution
           and on the system load; see time(7).  (But see BUGS below.)  Upon expi‐
           ration,  a  signal will be generated and the timer reset.  If the timer
           expires while the process is active (always  true  for  ITIMER_VIRTUAL)
           the signal will be delivered immediately when generated.  Otherwise the
           delivery will be offset by a small time dependent on the  system  load‐
           ing.

    RETURN VALUE
           On  success,  zero is returned.  On error, -1 is returned, and errno is
           set appropriately.

    ERRORS
           EFAULT new_value, old_value, or curr_value is not valid a pointer.

           EINVAL which is not one of ITIMER_REAL, ITIMER_VIRTUAL, or ITIMER_PROF;
                  or  (since Linux 2.6.22) one of the tv_usec fields in the struc‐
                  ture pointed to by new_value contains a value outside the  range
                  0 to 999999.

    CONFORMING TO
           POSIX.1-2001,  SVr4,  4.4BSD  (this  call  first  appeared  in 4.2BSD).
           POSIX.1-2008 marks getitimer() and setitimer()  obsolete,  recommending
           the  use  of  the POSIX timers API (timer_gettime(2), timer_settime(2),
           etc.) instead.

    NOTES
           A child created via fork(2) does  not  inherit  its  parent's  interval
           timers.  Interval timers are preserved across an execve(2).

           POSIX.1 leaves the interaction between setitimer() and the three inter‐
           faces alarm(2), sleep(3), and usleep(3) unspecified.

           The standards are silent on the meaning of the call:

               setitimer(which, NULL, &old_value);

           Many systems (Solaris, the BSDs, and  perhaps  others)  treat  this  as
           equivalent to:

               getitimer(which, &old_value);

           In  Linux,  this  is treated as being equivalent to a call in which the
           new_value fields are zero; that is, the timer is disabled.   Don't  use
           this Linux misfeature: it is nonportable and unnecessary.
票数 1
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/308152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档