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
| #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <time.h> #include <errno.h> #include <string.h> #include <signal.h> #include <unistd.h>
// 信号处理函数 void signal_handler(int sig) { printf(" 接收到信号 %d\n", sig); }
int main() { struct timespec request, remain, start, end; int result; printf("=== Clock_nanosleep 函数示例 ===\n"); // 示例1: 相对时间睡眠 printf("\n示例1: 相对时间睡眠\n"); // 睡眠100毫秒 request.tv_sec = 0; request.tv_nsec = 100000000; // 100毫秒 = 100,000,000纳秒 if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) { perror(" 获取开始时间失败"); } printf(" 开始睡眠: %ld.%09ld 秒\n", start.tv_sec, start.tv_nsec); result = clock_nanosleep(CLOCK_MONOTONIC, 0, &request, NULL); if (result == -1) { if (errno == EINTR) { printf(" 睡眠被信号中断\n"); } else { printf(" 睡眠失败: %s\n", strerror(errno)); } } else { printf(" 睡眠完成\n"); if (clock_gettime(CLOCK_MONOTONIC, &end) == -1) { perror(" 获取结束时间失败"); } else { long long actual_sleep = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec); printf(" 实际睡眠时间: %lld 纳秒\n", actual_sleep); } } // 示例2: 绝对时间睡眠 printf("\n示例2: 绝对时间睡眠\n"); // 获取当前时间 if (clock_gettime(CLOCK_REALTIME, &start) == 0) { printf(" 当前时间: %ld.%09ld 秒\n", start.tv_sec, start.tv_nsec); // 设置绝对睡眠时间(当前时间+2秒) struct timespec absolute_time; absolute_time.tv_sec = start.tv_sec + 2; absolute_time.tv_nsec = start.tv_nsec; printf(" 绝对睡眠时间: %ld.%09ld 秒\n", absolute_time.tv_sec, absolute_time.tv_nsec); result = clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &absolute_time, NULL); if (result == -1) { if (errno == EINTR) { printf(" 绝对时间睡眠被信号中断\n"); } else { printf(" 绝对时间睡眠失败: %s\n", strerror(errno)); } } else { printf(" 绝对时间睡眠完成\n"); } } // 示例3: 被信号中断的睡眠 printf("\n示例3: 被信号中断的睡眠\n"); // 设置信号处理 signal(SIGUSR1, signal_handler); // 启动另一个线程发送信号 pid_t pid = fork(); if (pid == 0) { // 子进程:延迟发送信号 sleep(1); kill(getppid(), SIGUSR1); exit(0); } else if (pid > 0) { // 父进程:长时间睡眠 request.tv_sec = 5; request.tv_nsec = 0; printf(" 开始5秒睡眠,1秒后会被信号中断\n"); result = clock_nanosleep(CLOCK_MONOTONIC, 0, &request, &remain); if (result == -1 && errno == EINTR) { printf(" 睡眠被信号中断\n"); printf(" 剩余时间: %ld.%09ld 秒\n", remain.tv_sec, remain.tv_nsec); } wait(NULL); // 等待子进程结束 } // 示例4: 错误处理演示 printf("\n示例4: 错误处理演示\n"); // 使用无效的时钟ID request.tv_sec = 1; request.tv_nsec = 0; result = clock_nanosleep(999, 0, &request, NULL); if (result == -1) { if (errno == EINVAL) { printf(" 无效时钟ID错误处理正确: %s\n", strerror(errno)); } } // 使用无效的时间值 request.tv_sec = -1; request.tv_nsec = 0; result = clock_nanosleep(CLOCK_MONOTONIC, 0, &request, NULL); if (result == -1) { if (errno == EINVAL) { printf(" 无效时间值错误处理正确: %s\n", strerror(errno)); } } // 使用过大的纳秒值 request.tv_sec = 0; request.tv_nsec = 1000000000; // 10亿纳秒 = 1秒,但应该 < 1秒 result = clock_nanosleep(CLOCK_MONOTONIC, 0, &request, NULL); if (result == -1) { if (errno == EINVAL) { printf(" 纳秒值过大错误处理正确: %s\n", strerror(errno)); } } // 示例5: 不同时钟的睡眠效果 printf("\n示例5: 不同时钟的睡眠效果\n"); printf("CLOCK_REALTIME睡眠:\n"); printf(" - 基于系统实时时间\n"); printf(" - 受系统时间调整影响\n"); printf(" - 适用于绝对时间睡眠\n\n"); printf("CLOCK_MONOTONIC睡眠:\n"); printf(" - 基于单调递增时间\n"); printf(" - 不受系统时间调整影响\n"); printf(" - 适用于相对时间睡眠\n\n"); // 示例6: 高精度定时器演示 printf("示例6: 高精度定时器演示\n"); printf("创建100毫秒间隔的定时器循环:\n"); struct timespec interval; interval.tv_sec = 0; interval.tv_nsec = 100000000; // 100毫秒 for (int i = 0; i < 5; i++) { if (clock_gettime(CLOCK_MONOTONIC, &start) == 0) { printf(" 第%d次: 时间 %ld.%09ld\n", i+1, start.tv_sec, start.tv_nsec); } result = clock_nanosleep(CLOCK_MONOTONIC, 0, &interval, NULL); if (result == -1) { if (errno == EINTR) { printf(" 第%d次: 睡眠被中断\n", i+1); break; } } } // 示例7: 睡眠精度测试 printf("\n示例7: 睡眠精度测试\n"); struct timespec sleep_times[] = { {0, 1000}, // 1微秒 {0, 10000}, // 10微秒 {0, 100000}, // 100微秒 {0, 1000000}, // 1毫秒 {0, 10000000}, // 10毫秒 {0, 100000000}, // 100毫秒 {1, 0} // 1秒 }; const char *time_labels[] = { "1微秒", "10微秒", "100微秒", "1毫秒", "10毫秒", "100毫秒", "1秒" }; printf("睡眠精度测试结果:\n"); for (int i = 0; i < 7; i++) { if (clock_gettime(CLOCK_MONOTONIC, &start) == 0) { result = clock_nanosleep(CLOCK_MONOTONIC, 0, &sleep_times[i], NULL); if (clock_gettime(CLOCK_MONOTONIC, &end) == 0) { long long actual = (end.tv_sec - start.tv_sec) * 1000000000LL + (end.tv_nsec - start.tv_nsec); long long requested = sleep_times[i].tv_sec * 1000000000LL + sleep_times[i].tv_nsec; long long diff = actual - requested; printf(" %-8s: 请求%8lld ns, 实际%8lld ns, 误差%+6lld ns\n", time_labels[i], requested, actual, diff); } } } // 示例8: 实际应用场景 printf("\n示例8: 实际应用场景\n"); // 场景1: 实时系统定时 printf("场景1: 实时系统定时\n"); printf("在实时应用中确保精确的时间间隔\n"); // 场景2: 性能基准测试 printf("\n场景2: 性能基准测试\n"); printf("提供精确的延迟控制用于性能测试\n"); // 场景3: 动画和游戏循环 printf("\n场景3: 动画和游戏循环\n"); printf("维持稳定的帧率和更新频率\n"); // 场景4: 网络超时控制 printf("\n场景4: 网络超时控制\n"); printf("实现精确的网络操作超时机制\n"); printf("\n总结:\n"); printf("clock_nanosleep提供纳秒级精度的睡眠功能\n"); printf("支持相对时间和绝对时间两种模式\n"); printf("比传统sleep函数更加灵活和精确\n"); printf("正确处理信号中断和剩余时间计算\n"); printf("适用于需要高精度时间控制的应用场景\n"); return 0; }
|