use setitimer raise signal interval-granuated by seconds and microseconds

简介:
在程序中如果要设置定时器, 简单的可以使用sleep, alarm. 他们的时间单位都是秒.
NAME
       alarm - set an alarm clock for delivery of a signal

SYNOPSIS
       #include <unistd.h>

       unsigned int alarm(unsigned int seconds);
NAME
       sleep - Sleep for the specified number of seconds

SYNOPSIS
       #include <unistd.h>

       unsigned int sleep(unsigned int seconds);

如果要设置更细的时间间隔, 需要使用setitimer, 下面举个例子 :
程序间隔0秒1000微秒后触发SIGALRM信号. 

[root@db-172-16-3-150 zzz]# cat d.c
#include <stdio.h>
#include <signal.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>

// 自定义handler函数.
void timeout (int sig) {
  fprintf(stdout, "sig:%i, time is up.\n", sig);
  exit(1);
}

int main() {
  // 准备修改SIGALRM信号的处理函数
  struct sigaction action;
  action.sa_handler = timeout;
  sigemptyset(&action.sa_mask);
  action.sa_flags=0;
  sigaction(SIGALRM, &action, NULL);
  // 0秒, 0微秒
  struct timeval timeout_t1 = {0, 0};
  // 1秒, 1000微秒
  struct timeval timeout_t2 = {1, 1000};
  // 设置时间间隔 
  struct itimerval timeout_it;
  // 设置next value
  timeout_it.it_interval = timeout_t1;
  // 设置current value, The element it_value is set to the amount of time remaining on the timer, or zero if the timer is disabled.
  // 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.
  timeout_it.it_value = timeout_t2;
  // 配置计时器, 
  setitimer(ITIMER_REAL, &timeout_it, NULL);
  // 模拟等待100秒, 当1秒1000微秒到达后, 将触发SIGALRM信号, 调用timeout函数. 退出.
  // 所以程序不会sleep 100秒.
  sleep(100);
  return 0;
}


【参考】
1. man 7 time

TIME(7)                    Linux Programmer’s Manual                   TIME(7)

NAME
       time - overview of time

DESCRIPTION
   Real time and process time
       Real  time is defined as time measured from some fixed point, either from a standard point in the past (see the
       description of the Epoch and calendar time below), or from some point (e.g., the start) in the life of  a  pro-
       cess (elapsed time).

       Process  time  is defined as the amount of CPU time used by a process.  This is sometimes divided into user and
       system components.  User CPU time is the time spent executing code in user mode.  System CPU time is  the  time
       spent  by  the  kernel  executing  in system mode on behalf of the process (e.g., executing system calls).  The
       time(1) command can be used to determine the amount of CPU time consumed during the execution of a program.   A
       program can determine the amount of CPU time it has consumed using times(2), getrusage(2), or clock(3).

   The Hardware Clock
       Most computers have a (battery-powered) hardware clock which the kernel reads at boot time in order to initial-
       ize the software clock.  For further details, see rtc(4) and hwclock(8).

   The Software Clock, HZ, and Jiffies
       The accuracy of many system calls and timestamps is limited by the resolution of the software  clock,  a  clock
       maintained by the kernel which measures time in jiffies.  The size of a jiffy is determined by the value of the
       kernel constant HZ.  The value of HZ varies across kernel versions and hardware platforms.  On x86  the  situa-
       tion  is  as  follows:  on kernels up to and including 2.4.x, HZ was 100, giving a jiffy value of 0.01 seconds;
       starting with 2.6.0, HZ was raised to 1000, giving a jiffy of 0.001 seconds; since kernel 2.6.13, the HZ  value
       is  a  kernel  configuration  parameter and can be 100, 250 (the default) or 1000, yielding a jiffies value of,
       respectively, 0.01, 0.004, or 0.001 seconds.

   The Epoch
       Unix systems represent time in seconds since the Epoch, which is defined as 0:00:00 UTC on  the  morning  of  1
       January 1970.

       A  program  can determine the calendar time using gettimeofday(2), which returns time (in seconds and microsec-
       onds) that have elapsed since the Epoch; time(2) provides similar information, but only with  accuracy  to  the
       nearest second.  The system time can be changed using settimeofday(2).

   Broken-down time
       Certain  library  functions  use  a structure of type tm to represent broken-down time, which stores time value
       separated out into distinct components (year, month, day, hour,  minute,  second,  etc.).   This  structure  is
       described  in ctime(3), which also describes functions that convert between calendar time and broken-down time.
       Functions for converting between broken-down  time  and  printable  string  representations  of  the  time  are
       described in ctime(3), strftime(3), and strptime(3).

   Sleeping and Setting Timers
       Various system calls and functions allow a program to sleep (suspend execution) for a specified period of time;
       see nanosleep(2) and sleep(3).

       Various system calls allow a process to set a timer that expires at some point in the future, and optionally at
       repeated intervals; see alarm(2), getitimer(2), and timer_create(3).

2. man setitimer
GETITIMER(2)               Linux Programmer’s Manual              GETITIMER(2)

NAME
       getitimer, setitimer - get or set value of an interval timer

SYNOPSIS
       #include <sys/time.h>

       int getitimer(int which, struct itimerval *value);
       int setitimer(int which, const struct itimerval *value,
                     struct itimerval *ovalue);

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

       ITIMER_REAL    decrements in real time, and delivers SIGALRM upon expiration.

       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 pro-
                      cess.   Coupled with ITIMER_VIRTUAL, this timer is usually used to profile the time spent by the
                      application in user and kernel 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 {
                long tv_sec;                /* seconds */
                long tv_usec;               /* microseconds */
            };

       The function getitimer() fills the structure indicated by value with the current setting for  the  timer  indi-
       cated 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 indicated timer to the value in value.  If ovalue is non-zero, 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 afterwards, which depends
       on the system timer resolution and on the system load.  (But see BUGS below.)  Upon expiration, 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 loading.

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

3. man alarm
ALARM(2)                   Linux Programmer’s Manual                  ALARM(2)

NAME
       alarm - set an alarm clock for delivery of a signal

SYNOPSIS
       #include <unistd.h>

       unsigned int alarm(unsigned int seconds);

DESCRIPTION
       alarm() arranges for a SIGALRM signal to be delivered to the process in seconds seconds.

       If seconds is zero, no new alarm() is scheduled.

       In any event any previously set alarm() is cancelled.

RETURN VALUE
       alarm()  returns  the number of seconds remaining until any previously scheduled alarm was due to be delivered,
       or zero if there was no previously scheduled alarm.

4. man sigaction
SIGACTION(2)               Linux Programmer’s Manual              SIGACTION(2)

NAME
       sigaction - examine and change a signal action

SYNOPSIS
       #include <signal.h>

       int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

DESCRIPTION
       The sigaction() system call is used to change the action taken by a process on receipt of a specific signal.

       signum specifies the signal and can be any valid signal except SIGKILL and SIGSTOP.

       If  act is non-null, the new action for signal signum is installed from act.  If oldact is non-null, the previ-
       ous action is saved in oldact.

       The sigaction structure is defined as something like

              struct sigaction {
                  void (*sa_handler)(int);
                  void (*sa_sigaction)(int, siginfo_t *, void *);
                  sigset_t sa_mask;
                  int sa_flags;
                  void (*sa_restorer)(void);
              }

       On some architectures a union is involved: do not assign to both sa_handler and sa_sigaction.

       The sa_restorer element is obsolete and should not be used.  POSIX does not specify a sa_restorer element.

       sa_handler specifies the action to be associated with signum and may be SIG_DFL for the default action, SIG_IGN
       to ignore this signal, or a pointer to a signal handling function.  This function receives the signal number as
       its only argument.

       If SA_SIGINFO is specified in sa_flags, then sa_sigaction (instead of sa_handler) specifies the signal-handling
       function  for signum.  This function receives the signal number as its first argument, a pointer to a siginfo_t
       as its second argument and a pointer to a ucontext_t (cast to void *) as its third argument.

       sa_mask gives a mask of signals which should be blocked during execution of the signal handler.   In  addition,
       the signal which triggered the handler will be blocked, unless the SA_NODEFER flag is used.

       sa_flags  specifies  a  set of flags which modify the behaviour of the signal handling process. It is formed by
       the bitwise OR of zero or more of the following:

              SA_NOCLDSTOP
                     If signum is SIGCHLD, do not receive notification when child  processes  stop  (i.e.,  when  they
                     receive  one of SIGSTOP, SIGTSTP, SIGTTIN or SIGTTOU) or resume (i.e., they receive SIGCONT) (see
                     wait(2)).

              SA_NOCLDWAIT
                     (Linux 2.6 and later) If signum is SIGCHLD, do not transform children into zombies when they ter-
                     minate.  See also waitpid(2).

              SA_RESETHAND
                     Restore  the  signal  action  to  the  default  state  once  the  signal handler has been called.
                     SA_ONESHOT is an obsolete, non-standard synonym for this flag.

              SA_ONSTACK
                     Call the signal handler on an alternate signal stack provided by sigaltstack(2).  If an alternate
                     stack is not available, the default stack will be used.

              SA_RESTART
                     Provide behaviour compatible with BSD signal semantics by making certain system calls restartable
                     across signals.

              SA_NODEFER
                     Do not prevent the signal from being received from within its own signal handler.   SA_NOMASK  is
                     an obsolete, non-standard synonym for this flag.

              SA_SIGINFO
                     The  signal handler takes 3 arguments, not one.  In this case, sa_sigaction should be set instead
                     of sa_handler.  (The sa_sigaction field was added in Linux 2.1.86.)

相关文章
|
9月前
已解决 RuntimeError: There is no current event loop in thread ‘Thread-1‘.
Jetson Xavier NX 报错 RuntimeError: There is no current event loop in thread 'Thread-1'.异常错误,已解决
146 0
已解决 RuntimeError: There is no current event loop in thread ‘Thread-1‘.
|
5月前
|
网络协议 Cloud Native
为什么需要 TIME_WAIT 状态
为什么需要 TIME_WAIT 状态
为什么需要 TIME_WAIT 状态
|
6月前
Time
Time
37 0
|
Unix
TIME
1143 0
|
网络协议 测试技术 Go
|
网络协议 关系型数据库 MySQL