在服务端程序设计中,与时间有关的常见任务有:
获取当前时间,计算时间间隔;
定时操作,比如在预定的时间执行一项任务,或者在一段延时之后执行一项任务。
Linux 时间函数
Linux 的计时函数,用于获得当前时间:
time(2) / time_t (秒)
ftime(3) / struct timeb (毫秒)
gettimeofday(2) / struct timeval (微秒)
clock_gettime(2) / struct timespec (纳秒)
gmtime / localtime / timegm / mktime / strftime / struct tm (这些与当前时间无关)
定时函数,用于让程序等待一段时间或安排计划任务:
sleep
alarm
getitimer / setitimer
timer_create / timer_settime / timer_gettime / timer_delete
timerfd_create / timerfd_gettime / timerfd_settime
条件变量pthread_cond_timedwait实现
IO多路复用select, epoll实现
一般情况下
获取当前时间常用
gettimerofday,因为它的精度是1us,并且在x86平台上它是用户态实现的,没有系统调用和上下文切换的开销。
定时函数中:
sleep / alarm / usleep 在实现时有可能用了信号 SIGALRM,在多线程程序中处理信号是个相当麻烦的事情,应当尽量避免。(近期我会写一篇博客仔细讲讲“多线程、RAII、fork() 与信号”)
nanosleep 和 clock_nanosleep 是线程安全的,但是在非阻塞网络编程中,绝对不能用让线程挂起的方式来等待一段时间,程序会失去响应。正确的做法是注册一个时间回调函数。
getitimer 和 timer_create 也是用信号来 deliver 超时,在多线程程序中也会有麻烦。timer_create 可以指定信号的接收方是进程还是线程,算是一个进步,不过在信号处理函数(signal handler)能做的事情实在很受限。
timerfd_create 把时间变成了一个文件描述符,该“文件”在定时器超时的那一刻变得可读,这样就能很方便地融入到 select/poll 框架中,用统一的方式来处理 IO 事件和超时事件。l
利用select, epoll的timeout实现定时功能,它们的缺点是定时精度只有毫秒,远低于 timerfd_settime 的定时精度。
实现
下面是用timer_create实现的一个定时器:
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
#include
#include
#include
#include
#include
#include
void sig_handler(int signo)
{
switch(signo) {
case SIGUSR1:
printf("receive sigusr1! \n");
break;
case SIGALRM:
printf("receive sigarlm!\n");
break;
}
}
int main()
{
/**
struct sigaction
{
void (*sa_handler)(int);信号响应函数地址
void (*sa_sigaction)(int, siginfo_t *, void *); 但sa_flags为SA——SIGINFO时才使用
sigset_t sa_mask; 说明一个信号集在调用捕捉函数之前,会加入进程的屏蔽中,当捕捉函数返回时,还原
int sa_flags;
void (*sa_restorer)(void);未用
};
*/
timer_t timer1, timer2;
struct sigevent evp1, evp2;
struct sigaction act;
//for timer1
memset(&act, 0, sizeof(act));
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
if (sigaction(SIGUSR1, &act, NULL) == -1) {
perror("fail to sigaction");
exit(-1);
}
//for timer2
memset(&act, 0, sizeof(act));
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
if (sigaction(SIGALRM, &act, NULL) == -1) {
perror("fail to sigaction");
exit(-1);
}
//for timer1
memset(&evp1, 0, sizeof(struct sigevent));
evp1.sigev_signo = SIGUSR1;
evp1.sigev_notify = SIGEV_SIGNAL;
if (timer_create(CLOCK_REALTIME, &evp1, &timer1) == -1) {
perror("fail to timer_create");
exit(-1);
}
struct itimerspec it;
it.it_interval.tv_sec = 2;
it.it_interval.tv_nsec = 0;
it.it_value.tv_sec = 1;
it.it_value.tv_nsec = 0;
if (timer_settime(timer1, 0, &it, 0) == -1) {
perror("fail to timer_settime");
exit(-1);
}
//for timer2
memset(&evp2, 0, sizeof(struct sigevent));
evp2.sigev_signo = SIGALRM;
evp2.sigev_notify = SIGEV_SIGNAL;
if (timer_create(CLOCK_REALTIME, &evp2, &timer2) == -1) {
perror("fail to timer_create");
exit(-1);
}
it.it_interval.tv_sec = 4;
it.it_interval.tv_nsec = 0;
it.it_value.tv_sec = 2;
it.it_value.tv_nsec = 0;
if (timer_settime(timer2, 0, &it, 0) == -1) {
perror("fail to timer_settime");
exit(-1);
}
for(;;);
return 0;
}
以及一个用setitimer实现的定时器
setitimer中的第一个参数有三类:
这里说得很清楚。
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 process. 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.
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
#include
#include
#include
#include
void timer_handler (int signum)
{
switch(signum) {
case SIGALRM:
printf("sigarlm !\n");
break;
case SIGVTALRM:
printf("sigvtalrm !\n");
break;
}
}
int main ()
{
struct sigaction sa;
struct itimerval timer;
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGVTALRM, &sa, NULL);
sa.sa_handler = &timer_handler;
sigaction(SIGALRM, &sa, NULL);
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 250000;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 250000;
setitimer (ITIMER_REAL, &timer, NULL);
timer.it_value.tv_sec = 1;
timer.it_value.tv_usec = 0;
timer.it_interval.tv_sec = 1;
timer.it_interval.tv_usec = 0;
setitimer (ITIMER_VIRTUAL, &timer, NULL);
while (1);
- 浏览: 36789 次
相关推荐
本文将深入探讨“基于Linux定时器管理器”的相关知识点,包括定时器的类型、工作原理以及如何添加、删除定时器,并对`end_timer_1`这个文件可能涉及的内容进行分析。 首先,让我们了解Linux中的定时器类型。主要有...
在深入探讨ARM Linux定时器驱动之前,我们先理解一下定时器的基本概念。 定时器是一种硬件或软件机制,能够在一个预设的时间间隔后触发一个事件。在Linux中,定时器分为硬件定时器和软件定时器。硬件定时器由CPU...
Linux 定时器编程详解 Linux 定时器编程是指在 Linux 系统中使用定时器来触发某些事件或执行某些任务的编程技术。定时器编程可以帮助开发者实现各种定时任务,提高系统的实时性和可靠性。 Linux 中的定时器编程...
### Linux定时器例子详解 #### 一、引言 Linux定时器是系统内核提供的一种机制,用于在指定时间间隔后触发特定事件或信号。它主要用于实现延时操作或者周期性任务调度。本文将深入探讨Linux定时器的具体实现方式,...
本篇将深入讲解Linux定时器及其在示例中的应用,特别是`timer_create`和`timer_settime`这两个函数的使用。 首先,Linux提供了两种主要类型的定时器:实时定时器和进程虚拟定时器。实时定时器与系统时钟同步,而...
在这个“Linux定时器代码”主题中,我们将深入探讨与时间相关的开发,特别是与S3C2440 ARM处理器的定时器相关的内容。 首先,S3C2440是一款基于ARM920T内核的微处理器,广泛应用于嵌入式系统,如移动设备和消费电子...
在本示例中,"linux 定时器 测试可用"的标题和描述表明这是一个关于Linux定时器的实践教程,其中包含一个已经验证过的示例代码。下面我们将深入探讨Linux定时器的概念、类型、使用方法以及如何进行测试。 1. **...
以下将详细阐述S3C2440 Linux定时器驱动的相关知识点。 首先,我们来看"ioremap"这个概念。在Linux内核中,ioremap函数用于映射硬件设备的I/O地址到虚拟内存空间,以便于CPU能够以常规方式访问这些硬件寄存器。S3C...
Linux定时器任务详解知识点: 1. Linux中定时器任务的基本概念 在Linux系统中,定时器任务是指用户设置的一系列操作,这些操作按照预定的时间间隔或特定的时间点自动执行。使用定时器任务可以有效地进行周期性的...
本文将深入探讨Linux定时器的使用,包括其类型、工作原理以及如何在实际编程中应用。 首先,我们需要了解Linux中的两种主要定时器类型:软定时器(Software Timers)和硬定时器(Hardware Timers)。软定时器是基于...
理解并熟练运用Linux定时器,可以提升你在系统编程和后台服务开发中的能力,为实现复杂的定时任务提供强大的工具。无论是简单的超时检查还是复杂的调度需求,Linux定时器都能提供可靠的解决方案。
Linux定时器是操作系统提供的一种机制,允许程序在特定时间间隔后执行特定操作。在Linux中,有三种类型的定时器:ITIMER_REAL、ITIMER_VIRTUAL和ITIMER_PROF,它们各自有不同的用途。 1. ITIMER_REAL:实时计数...
本文将深入探讨Linux定时器的工作原理、类型以及如何通过发送SIGALRM信号来触发定时器。 首先,我们需要理解Linux中的两种主要定时器类型:POSIX定时器和系统V定时器。POSIX定时器是标准C库提供的,符合POSIX.1b...
### Linux定时器底层处理及编程 #### 一、Linux内核的时间管理 在Linux操作系统中,时间管理扮演着至关重要的角色。它不仅支撑着整个系统的正常运作,还为各种应用程序和服务提供时间相关的功能支持。本章节将深入...
Linux操作系统中的定时器是系统...综上所述,Linux定时器结构和机理是操作系统中的关键元素,它们确保了任务的准确调度、系统时钟的管理和资源的有效利用。理解和掌握这些知识对于进行Linux系统开发和优化至关重要。
//linux只允许单进程拥有一个定时器,因此在linux下的单进程中要使用多个定时器,则需要自己维护管理 // //这个实现允许用户使用多个自定义的定时器,每个自定义的定时器将周期地被触发直到其被删除。实现的主要思路...
Linux 定时器和 Jiffies Linux 操作系统中有三个重要的时间相关概念:HZ、Tick 和 Jiffies。这些概念都是与时间有关的变数或名词,它们之间存在紧密的关系,并且在 Linux 内核中扮演着重要的角色。 1. HZ HZ 是 ...
总之,RT-Linux的细粒度定时器实现是通过改进传统的Linux定时器机制,结合硬件特性,实现微秒级精度和多模式定时,从而提升了系统的实时响应能力,为实时应用提供了强有力的支持。然而,实时操作系统的优化是一个...
在深入探讨Linux定时器的相关知识点之前,我们先来理解一下定时器在Linux系统中的作用及其重要性。Linux定时器是操作系统内核中的一个重要组件,它主要用于实现基于时间的任务调度、事件处理以及各种与时间相关的...