Linux定时器管理-深入解析timer_*函数

linux定时器管理timer_* 函数详解

data-ad-format="fluid" data-ad-layout-key="-7k+ex-4a-9w+4a">

掌握Linux定时器管理,深入解析timer_*系列函数用法与示例,助力开发者高效控制任务调度,提升程序性能。

  1. 函数介绍

timer_ 函数系列*是Linux系统中用于定时器管理的一组函数,它们提供了精确的时间控制和定时功能。可以把timer_*函数想象成一个”精密时钟系统”,允许你设置各种类型的定时器,包括一次性定时器、周期性定时器、以及高精度定时器。

这些函数基于POSIX定时器标准,提供了比传统alarm()函数更强大和灵活的功能。timer_*函数可以:

  • 创建和管理多个定时器

  • 设置一次性或周期性定时

  • 指定定时器到期时的行为(发送信号或执行回调)

  • 精确控制定时器的时间间隔

  • 查询和修改定时器状态

使用场景:

  • 网络服务器中的超时控制

  • 实时系统中的周期性任务

  • 游戏开发中的帧率控制

  • 系统监控和定时检查

  • 多媒体应用中的同步控制

  1. 函数原型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <time.h>
#include <signal.h>

// 创建定时器
int timer_create(clockid_t clockid, struct sigevent *sevp, timer_t *timerid);

// 启动/修改定时器
int timer_settime(timer_t timerid, int flags,
const struct itimerspec *new_value,
struct itimerspec *old_value);

// 获取定时器时间
int timer_gettime(timer_t timerid, struct itimerspec *curr_value);

// 获取定时器超时次数
int timer_getoverrun(timer_t timerid);

// 删除定时器
int timer_delete(timer_t timerid);

  1. 功能

timer_*函数系列提供了完整的定时器管理功能:

  • timer_create: 创建一个新的定时器,指定时钟源和到期通知方式

  • timer_settime: 启动、停止或修改定时器的定时参数

  • timer_gettime: 查询定时器的当前状态和剩余时间

  • timer_getoverrun: 获取定时器的超限运行次数(当定时器到期但未被处理时)

  • timer_delete: 删除和清理定时器资源

  1. 参数

timer_create参数:

clockid: 时钟类型

  • 类型:clockid_t

  • 含义:指定定时器使用的时钟源

常用值:

  • CLOCK_REALTIME:系统实时时间

  • CLOCK_MONOTONIC:单调时钟(不会受系统时间调整影响)

  • CLOCK_PROCESS_CPUTIME_ID:进程CPU时间

  • CLOCK_THREAD_CPUTIME_ID:线程CPU时间

sevp: 信号事件结构

  • 类型:struct sigevent*

  • 含义:指定定时器到期时的通知方式

  • NULL表示使用默认的SIGALRM信号

timerid: 定时器ID

  • 类型:timer_t*

  • 含义:返回创建的定时器标识符

timer_settime参数:

timerid: 定时器ID

  • 类型:timer_t

  • 含义:要操作的定时器标识符

flags: 操作标志

  • 类型:int

  • 含义:控制定时器行为的标志

常用值:

  • 0:相对时间

  • TIMER_ABSTIME:绝对时间

new_value: 新的定时器设置

  • 类型:const struct itimerspec*

  • 含义:指定定时器的新参数

old_value: 旧的定时器设置

  • 类型:struct itimerspec*

  • 含义:返回定时器之前的设置(可为NULL)

  1. 返回值
  • 成功: 返回0

失败: 返回-1,并设置errno错误码

  • EINVAL:参数无效

  • ENOMEM:内存不足

  • EPERM:权限不足

  • EAGAIN:资源暂时不可用

  1. 相似函数或关联函数
  • alarm(): 传统的一次性定时器函数

  • setitimer(): 更灵活的间隔定时器函数

  • sleep()/usleep(): 简单的延迟函数

  • clock_gettime(): 获取时钟时间

  • nanosleep(): 高精度睡眠函数

  • signal()/sigaction(): 信号处理函数

  1. 示例代码

示例1:基础timer使用 - 简单定时器

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
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#include <errno.h>

// 定时器信号处理函数
void timer_handler(int sig, siginfo_t *si, void *uc) {
timer_t *tidp = si->si_value.sival_ptr;
printf("&#91;%ld] 定时器到期! 定时器ID: %p\n", time(NULL), (void*)*tidp);
}

int main() {
timer_t timerid;
struct sigevent sev;
struct itimerspec its;
struct sigaction sa;

printf("=== 基础定时器示例 ===\n");
printf("当前时间: %ld\n", time(NULL));

// 设置信号处理函数
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = timer_handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGRTMIN, &sa, NULL) == -1) {
perror("sigaction");
exit(EXIT_FAILURE);
}

// 创建定时器
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN;
sev.sigev_value.sival_ptr = &timerid;
if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) {
perror("timer_create");
exit(EXIT_FAILURE);
}

printf("定时器创建成功,ID: %p\n", (void*)timerid);

// 设置定时器:5秒后开始,每2秒触发一次
its.it_value.tv_sec = 5; // 初始延迟5秒
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 2; // 周期间隔2秒
its.it_interval.tv_nsec = 0;

if (timer_settime(timerid, 0, &its, NULL) == -1) {
perror("timer_settime");
exit(EXIT_FAILURE);
}

printf("定时器已启动:5秒后首次触发,之后每2秒触发一次\n");
printf("程序将运行20秒...\n\n");

// 等待定时器触发
sleep(20);

// 停止定时器
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;

if (timer_settime(timerid, 0, &its, NULL) == -1) {
perror("timer_settime");
exit(EXIT_FAILURE);
}

printf("\n定时器已停止\n");

// 删除定时器
if (timer_delete(timerid) == -1) {
perror("timer_delete");
exit(EXIT_FAILURE);
}

printf("定时器已删除\n");

return 0;
}

示例2:多种定时器类型和时钟源

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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>

#define NUM_TIMERS 4

timer_t timers&#91;NUM_TIMERS];
int timer_counts&#91;NUM_TIMERS] = {0};

// 定时器信号处理函数
void timer_handler(int sig, siginfo_t *si, void *uc) {
int timer_index = si->si_value.sival_int;

timer_counts&#91;timer_index]++;
printf("&#91;%ld] 定时器 %d 到期第 %d 次\n",
time(NULL), timer_index, timer_counts&#91;timer_index]);

// 演示timer_gettime
struct itimerspec curr_value;
if (timer_gettime(timers&#91;timer_index], &curr_value) == 0) {
printf(" 剩余时间: %ld.%09ld 秒\n",
curr_value.it_value.tv_sec, curr_value.it_value.tv_nsec);
}

// 演示timer_getoverrun
int overrun = timer_getoverrun(timers&#91;timer_index]);
if (overrun > 0) {
printf(" 超限运行: %d 次\n", overrun);
}
}

int main() {
struct sigaction sa;
struct sigevent sev;
struct itimerspec its;
int i;

printf("=== 多种定时器类型示例 ===\n");
printf("当前时间: %ld\n\n", time(NULL));

// 设置信号处理函数
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = timer_handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGRTMIN, &sa, NULL) == -1) {
perror("sigaction");
exit(EXIT_FAILURE);
}

// 创建不同类型的定时器
for (i = 0; i < NUM_TIMERS; i++) {
// 设置信号事件
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN;
sev.sigev_value.sival_int = i;

clockid_t clock_type;
const char* clock_name;

switch(i) {
case 0:
clock_type = CLOCK_REALTIME;
clock_name = "CLOCK_REALTIME";
break;
case 1:
clock_type = CLOCK_MONOTONIC;
clock_name = "CLOCK_MONOTONIC";
break;
case 2:
clock_type = CLOCK_PROCESS_CPUTIME_ID;
clock_name = "CLOCK_PROCESS_CPUTIME_ID";
break;
case 3:
clock_type = CLOCK_THREAD_CPUTIME_ID;
clock_name = "CLOCK_THREAD_CPUTIME_ID";
break;
default:
clock_type = CLOCK_REALTIME;
clock_name = "DEFAULT";
break;
}

// 创建定时器
if (timer_create(clock_type, &sev, &timers&#91;i]) == -1) {
printf("创建定时器 %d (%s) 失败: %s\n", i, clock_name, strerror(errno));
continue;
}

printf("定时器 %d (%s) 创建成功\n", i, clock_name);

// 设置不同的定时参数
switch(i) {
case 0: // 一次性定时器
its.it_value.tv_sec = 3 + i; // 3秒后触发
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 0; // 不重复
its.it_interval.tv_nsec = 0;
printf(" 设置为一次性定时器,%d秒后触发\n", 3 + i);
break;

case 1: // 短周期定时器
its.it_value.tv_sec = 2; // 2秒后首次触发
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 1; // 每1秒重复
its.it_interval.tv_nsec = 0;
printf(" 设置为周期性定时器,2秒后开始,每1秒触发\n");
break;

case 2: // 长周期定时器
its.it_value.tv_sec = 5; // 5秒后首次触发
its.it_value.tv_nsec = 500000000; // 500毫秒
its.it_interval.tv_sec = 3; // 每3秒重复
its.it_interval.tv_nsec = 0;
printf(" 设置为周期性定时器,5.5秒后开始,每3秒触发\n");
break;

case 3: // 快速定时器
its.it_value.tv_sec = 1; // 1秒后首次触发
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 0; // 每0.5秒重复
its.it_interval.tv_nsec = 500000000; // 500毫秒
printf(" 设置为周期性定时器,1秒后开始,每0.5秒触发\n");
break;
}

// 启动定时器
if (timer_settime(timers&#91;i], 0, &its, NULL) == -1) {
perror("timer_settime");
exit(EXIT_FAILURE);
}
}

printf("\n所有定时器已启动,程序运行20秒...\n\n");

// 运行一段时间观察定时器效果
sleep(20);

// 停止所有定时器
printf("\n=== 停止所有定时器 ===\n");
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;

for (i = 0; i < NUM_TIMERS; i++) {
if (timer_settime(timers&#91;i], 0, &its, NULL) == -1) {
printf("停止定时器 %d 失败\n", i);
} else {
printf("定时器 %d 已停止\n", i);
}
}

// 删除所有定时器
printf("\n=== 删除所有定时器 ===\n");
for (i = 0; i < NUM_TIMERS; i++) {
if (timer_delete(timers&#91;i]) == -1) {
printf("删除定时器 %d 失败\n", i);
} else {
printf("定时器 %d 已删除\n", i);
}
}

// 显示统计信息
printf("\n=== 定时器触发统计 ===\n");
for (i = 0; i < NUM_TIMERS; i++) {
printf("定时器 %d 触发次数: %d\n", i, timer_counts&#91;i]);
}

return 0;
}

示例3:高精度定时器和绝对时间定时

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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>

timer_t timerid;
int trigger_count = 0;

// 定时器信号处理函数
void timer_handler(int sig, siginfo_t *si, void *uc) {
trigger_count++;

struct timespec current_time;
clock_gettime(CLOCK_REALTIME, &current_time);

printf("&#91;%ld.%09ld] 定时器第 %d 次触发\n",
current_time.tv_sec, current_time.tv_nsec, trigger_count);
}

// 获取当前时间字符串
void print_current_time() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
printf("当前时间: %ld.%09ld\n", ts.tv_sec, ts.tv_nsec);
}

int main() {
struct sigaction sa;
struct sigevent sev;
struct itimerspec its;
struct timespec current_time;

printf("=== 高精度定时器和绝对时间示例 ===\n");
print_current_time();
printf("\n");

// 设置信号处理函数
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = timer_handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGRTMIN, &sa, NULL) == -1) {
perror("sigaction");
exit(EXIT_FAILURE);
}

// 创建定时器
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN;
sev.sigev_value.sival_ptr = &timerid;

if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) {
perror("timer_create");
exit(EXIT_FAILURE);
}

printf("高精度定时器创建成功\n");

// 示例1: 相对时间定时器(高精度)
printf("\n--- 相对时间定时器 ---\n");
print_current_time();

// 设置1.5秒的延迟定时器
its.it_value.tv_sec = 1;
its.it_value.tv_nsec = 500000000; // 500毫秒
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;

if (timer_settime(timerid, 0, &its, NULL) == -1) {
perror("timer_settime");
exit(EXIT_FAILURE);
}

printf("设置1.5秒延迟定时器...\n");
sleep(3); // 等待定时器触发

// 示例2: 周期性高精度定时器
printf("\n--- 周期性高精度定时器 ---\n");
print_current_time();

// 设置周期性定时器:0.1秒后开始,每0.2秒触发
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 100000000; // 100毫秒
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 200000000; // 200毫秒

if (timer_settime(timerid, 0, &its, NULL) == -1) {
perror("timer_settime");
exit(EXIT_FAILURE);
}

printf("设置周期性定时器:100毫秒后开始,每200毫秒触发\n");
printf("运行5秒观察效果...\n\n");

sleep(5);

// 停止定时器
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;

if (timer_settime(timerid, 0, &its, NULL) == -1) {
perror("timer_settime");
exit(EXIT_FAILURE);
}

printf("\n周期性定时器已停止\n");
printf("触发次数: %d\n", trigger_count);

// 示例3: 绝对时间定时器
printf("\n--- 绝对时间定时器 ---\n");
trigger_count = 0;

// 获取当前时间并设置5秒后的绝对时间
if (clock_gettime(CLOCK_REALTIME, &current_time) == -1) {
perror("clock_gettime");
exit(EXIT_FAILURE);
}

print_current_time();

// 设置绝对时间:当前时间+3秒
struct itimerspec abs_its;
abs_its.it_value.tv_sec = current_time.tv_sec + 3;
abs_its.it_value.tv_nsec = current_time.tv_nsec;
abs_its.it_interval.tv_sec = 0;
abs_its.it_interval.tv_nsec = 0;

printf("设置绝对时间定时器:3秒后触发\n");

if (timer_settime(timerid, TIMER_ABSTIME, &abs_its, NULL) == -1) {
perror("timer_settime (绝对时间)");
exit(EXIT_FAILURE);
}

sleep(5); // 等待定时器触发

// 示例4: 定时器状态查询
printf("\n--- 定时器状态查询 ---\n");

// 重新设置一个周期性定时器用于测试
its.it_value.tv_sec = 1;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 2;
its.it_interval.tv_nsec = 0;

if (timer_settime(timerid, 0, &its, NULL) == -1) {
perror("timer_settime");
exit(EXIT_FAILURE);
}

printf("设置新的周期性定时器:1秒后开始,每2秒触发\n");

// 查询定时器状态
sleep(1); // 等待首次触发后

struct itimerspec query_its;
if (timer_gettime(timerid, &query_its) == 0) {
printf("定时器状态查询结果:\n");
printf(" 到期间隔: %ld.%09ld 秒\n",
query_its.it_interval.tv_sec, query_its.it_interval.tv_nsec);
printf(" 剩余时间: %ld.%09ld 秒\n",
query_its.it_value.tv_sec, query_its.it_value.tv_nsec);
}

// 演示timer_getoverrun
printf("定时器超限运行测试(快速触发):\n");
sleep(6);

int overrun = timer_getoverrun(timerid);
printf("超限运行次数: %d\n", overrun);

// 清理
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
timer_settime(timerid, 0, &its, NULL);
timer_delete(timerid);

printf("\n所有测试完成\n");

return 0;
}

示例4:定时器在实际应用中的使用

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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#include <pthread.h>

#define MAX_TASKS 10
#define HEARTBEAT_INTERVAL 5

// 任务结构体
typedef struct {
int id;
char name&#91;50];
int interval_seconds;
time_t last_run;
int run_count;
} task_t;

task_t tasks&#91;MAX_TASKS];
int task_count = 0;
timer_t heartbeat_timer;
timer_t task_timers&#91;MAX_TASKS];
pthread_mutex_t task_mutex = PTHREAD_MUTEX_INITIALIZER;

// 添加任务
int add_task(int id, const char* name, int interval) {
if (task_count >= MAX_TASKS) {
return -1;
}

tasks&#91;task_count].id = id;
strncpy(tasks&#91;task_count].name, name, sizeof(tasks&#91;task_count].name) - 1);
tasks&#91;task_count].interval_seconds = interval;
tasks&#91;task_count].last_run = 0;
tasks&#91;task_count].run_count = 0;

return task_count++;
}

// 任务执行函数
void execute_task(int task_index) {
pthread_mutex_lock(&task_mutex);

time_t current_time = time(NULL);
tasks&#91;task_index].last_run = current_time;
tasks&#91;task_index].run_count++;

printf("&#91;%ld] 执行任务 %d (%s): 第 %d 次执行\n",
current_time,
tasks&#91;task_index].id,
tasks&#91;task_index].name,
tasks&#91;task_index].run_count);

pthread_mutex_unlock(&task_mutex);
}

// 任务定时器处理函数
void task_timer_handler(int sig, siginfo_t *si, void *uc) {
int task_index = si->si_value.sival_int;
execute_task(task_index);
}

// 心跳定时器处理函数
void heartbeat_handler(int sig, siginfo_t *si, void *uc) {
static int heartbeat_count = 0;
heartbeat_count++;

printf("&#91;%ld] 系统心跳 #%d\n", time(NULL), heartbeat_count);

// 显示所有任务状态
pthread_mutex_lock(&task_mutex);
printf(" 任务状态:\n");
for (int i = 0; i < task_count; i++) {
printf(" %s: 执行%d次, 最后执行: %s",
tasks&#91;i].name, tasks&#91;i].run_count,
tasks&#91;i].last_run ? ctime(&tasks&#91;i].last_run) : "从未执行\n");
if (tasks&#91;i].last_run) {
// 移除ctime返回的换行符
char* newline = strchr(ctime(&tasks&#91;i].last_run), '\n');
if (newline) *newline = '\0';
printf("%s\n", ctime(&tasks&#91;i].last_run));
}
}
pthread_mutex_unlock(&task_mutex);
}

// 初始化定时器系统
int init_timer_system() {
struct sigaction sa;

// 设置任务定时器信号处理
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = task_timer_handler;
sigemptyset(&sa.sa_mask);
if (sigaction(SIGRTMIN, &sa, NULL) == -1) {
perror("sigaction task");
return -1;
}

// 设置心跳定时器信号处理
sa.sa_sigaction = heartbeat_handler;
if (sigaction(SIGRTMIN + 1, &sa, NULL) == -1) {
perror("sigaction heartbeat");
return -1;
}

return 0;
}

// 启动任务定时器
int start_task_timer(int task_index) {
struct sigevent sev;
struct itimerspec its;

// 创建定时器
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN;
sev.sigev_value.sival_int = task_index;

if (timer_create(CLOCK_REALTIME, &sev, &task_timers&#91;task_index]) == -1) {
perror("timer_create task");
return -1;
}

// 设置定时器
its.it_value.tv_sec = tasks&#91;task_index].interval_seconds;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = tasks&#91;task_index].interval_seconds;
its.it_interval.tv_nsec = 0;

if (timer_settime(task_timers&#91;task_index], 0, &its, NULL) == -1) {
perror("timer_settime task");
return -1;
}

printf("任务定时器 %s 已启动,间隔 %d 秒\n",
tasks&#91;task_index].name, tasks&#91;task_index].interval_seconds);

return 0;
}

// 启动心跳定时器
int start_heartbeat_timer() {
struct sigevent sev;
struct itimerspec its;

// 创建心跳定时器
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIGRTMIN + 1;
sev.sigev_value.sival_int = 0;

if (timer_create(CLOCK_REALTIME, &sev, &heartbeat_timer) == -1) {
perror("timer_create heartbeat");
return -1;
}

// 设置心跳定时器(每5秒触发一次)
its.it_value.tv_sec = HEARTBEAT_INTERVAL;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = HEARTBEAT_INTERVAL;
its.it_interval.tv_nsec = 0;

if (timer_settime(heartbeat_timer, 0, &its, NULL) == -1) {
perror("timer_settime heartbeat");
return -1;
}

printf("心跳定时器已启动,间隔 %d 秒\n", HEARTBEAT_INTERVAL);

return 0;
}

int main() {
printf("=== 实际应用中的定时器系统 ===\n");
printf("启动时间: %s", ctime(&(time_t){time(NULL)}));

// 初始化定时器系统
if (init_timer_system() == -1) {
fprintf(stderr, "初始化定时器系统失败\n");
exit(EXIT_FAILURE);
}

// 添加一些测试任务
add_task(1, "数据备份", 10);
add_task(2, "日志清理", 15);
add_task(3, "状态检查", 5);
add_task(4, "性能监控", 3);

printf("已添加 %d 个任务\n", task_count);

// 启动所有任务定时器
for (int i = 0; i < task_count; i++) {
if (start_task_timer(i) == -1) {
fprintf(stderr, "启动任务定时器 %d 失败\n", i);
}
}

// 启动心跳定时器
if (start_heartbeat_timer() == -1) {
fprintf(stderr, "启动心跳定时器失败\n");
}

printf("\n定时器系统运行中...\n");
printf("程序将运行60秒,按Ctrl+C退出\n\n");

// 运行主循环
for (int i = 0; i < 60; i++) {
sleep(1);

// 每10秒显示一次统计信息
if ((i + 1) % 10 == 0) {
printf("&#91;%ld] === 运行统计 ===\n", time(NULL));
pthread_mutex_lock(&task_mutex);
for (int j = 0; j < task_count; j++) {
printf(" %s: 执行 %d 次\n",
tasks&#91;j].name, tasks&#91;j].run_count);
}
pthread_mutex_unlock(&task_mutex);
printf("==================\n\n");
}
}

// 清理定时器
printf("清理定时器...\n");

// 停止并删除心跳定时器
struct itimerspec stop_its = {{0, 0}, {0, 0}};
timer_settime(heartbeat_timer, 0, &stop_its, NULL);
timer_delete(heartbeat_timer);

// 停止并删除所有任务定时器
for (int i = 0; i < task_count; i++) {
timer_settime(task_timers&#91;i], 0, &stop_its, NULL);
timer_delete(task_timers&#91;i]);
}

printf("定时器系统已停止\n");

// 显示最终统计
printf("\n=== 最终统计 ===\n");
pthread_mutex_lock(&task_mutex);
for (int i = 0; i < task_count; i++) {
printf("%s: 执行 %d 次\n", tasks&#91;i].name, tasks&#91;i].run_count);
}
pthread_mutex_unlock(&task_mutex);

return 0;
}

编译和运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 编译示例1
gcc -o timer_example1 timer_example1.c -lrt
./timer_example1

# 编译示例2
gcc -o timer_example2 timer_example2.c -lrt
./timer_example2

# 编译示例3
gcc -o timer_example3 timer_example3.c -lrt
./timer_example3

# 编译示例4
gcc -o timer_example4 timer_example4.c -lrt -lpthread
./timer_example4

重要注意事项

链接库: 使用timer_*函数需要链接实时库(-lrt)

信号处理: 定时器通常通过信号通知,需要注意信号安全

精度限制: 实际精度受系统调度和负载影响

资源管理: 必须正确删除定时器以避免资源泄漏

线程安全: 在多线程环境中使用时需要适当的同步

错误处理: 所有timer_*函数都可能失败,必须检查返回值

时钟选择: 不同时钟源适用于不同的应用场景

通过这些示例,你可以理解timer_*函数在定时控制方面的强大功能,它们为Linux应用程序提供了精确、灵活的时间管理能力。

https://www.calcguide.tech/2025/08/05/linux定时器管理timer/

getitimer系统调用及示例

data-ad-format="auto" data-full-width-responsive="true">