Skip to content

System Timer

Alarm

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <signal.h>

void timer(int sig)
{
  if (SIGALRM == sig)
  {
    printf("timer\n");
    alarm(1); //we contimue set the timer
  }
  return;
}
int main()
{
  signal(SIGALRM, timer); //relate the signal and function
  alarm(1);               //trigger the timer
  getchar();
  return 0;
}

Result:


Settime

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*

gcc main.c -lrt

*/

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>

#define errExit(msg)    \
  do                    \
  {                     \
    perror(msg);        \
    exit(EXIT_FAILURE); \
  } while (0)

void timer_handler()
{

  time_t t;
  time(&t);
  printf("\n current time is : %s",ctime(&t));

  return;
}

int main(int argc, char *argv[])
{
  timer_t timerid;
  struct sigevent sev;
  struct itimerspec its;

  sev.sigev_notify = SIGEV_SIGNAL;
  sev.sigev_signo = SIGUSR1;
  sev.sigev_value.sival_ptr = &timerid;
  signal(SIGUSR1, timer_handler);

  if (timer_create(CLOCK_MONOTONIC, &sev, &timerid) == -1)
  {
    errExit("timer_create");
  }

  its.it_value.tv_sec = 1;
  its.it_value.tv_nsec = 0;
  its.it_interval.tv_sec = 0;
  its.it_interval.tv_nsec = 500000000;

  /* 啓動定時器 */
  if (timer_settime(timerid, 0, &its, NULL) == -1)
  {
    errExit("timer_settime");
  }

  while (1)
  {
    ; //sleep(1);
  }

  timer_delete(timerid);

  exit(EXIT_SUCCESS);
}

Result:


Setitimer

Example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*

https://www.itread01.com/content/1547016130.html

gcc main.c -lpthread
*/

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/time.h>
#include <pthread.h>

static int count = 0;

#define SEC 1
#define USEC 0

void timeout(int signal)
{
  printf("Get a SIGALRM, counts = %d!\n", count);
}

int on_timer()
{
  struct itimerval tick;
  memset(&tick, 0, sizeof(tick));
  tick.it_value.tv_sec = SEC;
  tick.it_value.tv_usec = USEC;
  tick.it_interval.tv_sec = 0;
  tick.it_interval.tv_usec = 0;
  if (setitimer(ITIMER_REAL, &tick, NULL) < 0)
    printf("Set timer failed!\n");
  return 0;
}

int off_timer()
{
  struct itimerval tick;
  memset(&tick, 0, sizeof(tick));
  tick.it_value.tv_sec = 0;
  tick.it_value.tv_usec = 0;
  tick.it_interval.tv_sec = 0;
  tick.it_interval.tv_usec = 0;
  if (setitimer(ITIMER_REAL, &tick, NULL) < 0)
    printf("Set timer failed!\n");
  return 0;
}

void *func(void *arg)
{
  while (1)
  {
    printf("hello...\n");
    count++;
    if (count % 2 == 0)
    {
      on_timer();
      sleep(2);
    }
    else
      off_timer();
  }
}

int main()
{
  int res = 0;

  signal(SIGALRM, timeout);

  on_timer();
  pthread_t fd;
  pthread_create(&fd, NULL, func, NULL);

  while (1)
  {
    sleep(20);
  }
  return 0;
}

Result:


Timerfd

Example:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// https://hackmd.io/@sysprog/linux-timerfd

#include <sys/timerfd.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h> /* Definition of uint64_t */

#define handle_error(msg) \
  do                      \
  {                       \
    perror(msg);          \
    exit(EXIT_FAILURE);   \
  } while (0)

static void
print_elapsed_time(void)
{
  static struct timespec start;
  struct timespec curr;
  static int first_call = 1;
  int secs, nsecs;

  if (first_call)
  {
    first_call = 0;

    if (clock_gettime(CLOCK_MONOTONIC, &start) == -1)
    {
      handle_error("clock_gettime");
    }
  }

  if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1)
  {
    handle_error("clock_gettime");
  }

  secs = curr.tv_sec - start.tv_sec;
  nsecs = curr.tv_nsec - start.tv_nsec;

  if (nsecs < 0)
  {
    secs--;
    nsecs += 1000000000;
  }

  printf("%d.%03d: ", secs, (nsecs + 500000) / 1000000);
}

int main(int argc, char *argv[])
{
  struct itimerspec new_value;
  int max_exp, fd;
  struct timespec now;
  uint64_t exp, tot_exp;
  ssize_t s;

  if ((argc != 2) && (argc != 4))
  {
    fprintf(stderr, "%s init-secs [interval-secs max-exp]\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  if (clock_gettime(CLOCK_REALTIME, &now) == -1)
  {
    handle_error("clock_gettime");
  }

  /* Create a CLOCK_REALTIME absolute timer with initial
       expiration and interval as specified in command line */

  new_value.it_value.tv_sec = now.tv_sec + atoi(argv[1]);
  new_value.it_value.tv_nsec = now.tv_nsec;

  if (argc == 2)
  {
    new_value.it_interval.tv_sec = 0;
    max_exp = 1;
  }
  else
  {
    new_value.it_interval.tv_sec = atoi(argv[2]);
    max_exp = atoi(argv[3]);
  }

  new_value.it_interval.tv_nsec = 0;

  fd = timerfd_create(CLOCK_REALTIME, 0);

  if (fd == -1)
  {
    handle_error("timerfd_create");
  }

  if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &new_value, NULL) == -1)
  {
    handle_error("timerfd_settime");
  }

  print_elapsed_time();
  printf("timer started\n");

  for (tot_exp = 0; tot_exp < max_exp;)
  {
    s = read(fd, &exp, sizeof(uint64_t));

    if (s != sizeof(uint64_t))
    {
      handle_error("read");
    }

    tot_exp += exp;
    print_elapsed_time();
    printf("read: %llu; total=%llu\n",
           (unsigned long long)exp,
           (unsigned long long)tot_exp);
  }
  exit(EXIT_SUCCESS);
}

Result:

$ ./a.out 0 1 3
0.000: timer started
0.000: read: 1; total=1
1.000: read: 1; total=2
2.000: read: 1; total=3

timer_alarm/ timer_select/ timer_setitimer/ timer_settime/ timer_timerfd/