clock_nanosleep系统调用及示例

41. clock_nanosleep - 高精度睡眠

函数介绍

clock_nanosleep系统调用提供纳秒级精度的睡眠功能,支持绝对时间和相对时间两种模式,比传统的nanosleep更加灵活。

函数原型

#include <time.h>int clock_nanosleep(clockid_t clock_id, int flags,const struct timespec *request,struct timespec *remain);

功能

使进程睡眠指定的时间,支持高精度纳秒级睡眠。

参数

  • clockid_t clock_id: 时钟ID
  • int flags: 标志位
    • 0: 相对时间睡眠
    • TIMER_ABSTIME: 绝对时间睡眠
  • const struct timespec *request: 请求睡眠的时间
  • struct timespec *remain: 剩余时间(被信号中断时)

返回值

  • 成功时返回0
  • 被信号中断时返回-1,并设置errno为EINTR
  • 失败时返回-1,并设置其他errno

相似函数

  • nanosleep(): 纳秒级睡眠
  • sleep(): 秒级睡眠
  • usleep(): 微秒级睡眠

示例代码

#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");// 使用无效的时钟IDrequest.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;
}

42. clock_settime - 设置时钟时间

函数介绍

clock_settime系统调用用于设置指定时钟的时间值。它允许程序修改系统时钟,主要用于时间同步和系统管理。

函数原型

#include <time.h>int clock_settime(clockid_t clk_id, const struct timespec *tp);

功能

设置指定时钟的时间值。

参数

  • clockid_t clk_id: 时钟ID(通常为CLOCK_REALTIME)
  • const struct timespec *tp: 指向timespec结构体的指针,包含新的时间值

返回值

  • 成功时返回0
  • 失败时返回-1,并设置errno

特殊限制

  • 需要CAP_SYS_TIME能力或root权限
  • 通常只能设置CLOCK_REALTIME时钟

相似函数

  • settimeofday(): 设置系统时间
  • stime(): 设置系统时间(已废弃)

示例代码

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>int main() {struct timespec current_time, new_time;int result;printf("=== Clock_settime 函数示例 ===\n");printf("当前用户 UID: %d\n", getuid());printf("当前有效 UID: %d\n", geteuid());// 示例1: 获取当前时间printf("\n示例1: 获取当前时间\n");if (clock_gettime(CLOCK_REALTIME, &current_time) == -1) {perror("  获取当前时间失败");} else {printf("  当前系统时间: %ld.%09ld 秒\n", current_time.tv_sec, current_time.tv_nsec);printf("  对应日期: %s", ctime(&current_time.tv_sec));}// 示例2: 权限检查printf("\n示例2: 权限检查\n");// 尝试设置时间(通常会失败)new_time.tv_sec = current_time.tv_sec;new_time.tv_nsec = current_time.tv_nsec;result = clock_settime(CLOCK_REALTIME, &new_time);if (result == -1) {if (errno == EPERM) {printf("  权限不足设置时间: %s\n", strerror(errno));printf("  说明: 需要CAP_SYS_TIME能力或root权限\n");} else {printf("  设置时间失败: %s\n", strerror(errno));}} else {printf("  时间设置成功\n");}// 示例3: 错误处理演示printf("\n示例3: 错误处理演示\n");// 使用无效的时钟IDresult = clock_settime(999, &new_time);if (result == -1) {if (errno == EINVAL) {printf("  无效时钟ID错误处理正确: %s\n", strerror(errno));}}// 使用无效的时间值struct timespec invalid_time;invalid_time.tv_sec = -1;invalid_time.tv_nsec = 0;result = clock_settime(CLOCK_REALTIME, &invalid_time);if (result == -1) {if (errno == EINVAL) {printf("  无效时间值错误处理正确: %s\n", strerror(errno));}}// 使用过大的纳秒值invalid_time.tv_sec = current_time.tv_sec;invalid_time.tv_nsec = 1000000000; // 10亿纳秒,应该 < 1秒result = clock_settime(CLOCK_REALTIME, &invalid_time);if (result == -1) {if (errno == EINVAL) {printf("  纳秒值过大错误处理正确: %s\n", strerror(errno));}}// 使用NULL指针result = clock_settime(CLOCK_REALTIME, NULL);if (result == -1) {if (errno == EFAULT) {printf("  NULL指针错误处理正确: %s\n", strerror(errno));}}// 示例4: 支持的时钟类型printf("\n示例4: 支持的时钟类型\n");printf("CLOCK_REALTIME:\n");printf("  - 系统实时钟\n");printf("  - 可以被设置\n");printf("  - 用于表示当前时间\n\n");printf("其他时钟类型:\n");printf("  - CLOCK_MONOTONIC: 通常不能设置\n");printf("  - CLOCK_PROCESS_CPUTIME_ID: 不能设置\n");printf("  - CLOCK_THREAD_CPUTIME_ID: 不能设置\n\n");// 示例5: 时间格式转换printf("示例5: 时间格式转换\n");if (clock_gettime(CLOCK_REALTIME, &current_time) == 0) {printf("  当前时间: %ld.%09ld 秒\n", current_time.tv_sec, current_time.tv_nsec);// 从日期字符串转换为time_tstruct tm time_info;strptime("2024-01-01 12:00:00", "%Y-%m-%d %H:%M:%S", &time_info);time_t new_time_t = mktime(&time_info);printf("  转换时间: %s", ctime(&new_time_t));// 转换为timespec格式struct timespec converted_time;converted_time.tv_sec = new_time_t;converted_time.tv_nsec = 0;printf("  timespec格式: %ld.%09ld 秒\n", converted_time.tv_sec, converted_time.tv_nsec);}// 示例6: 时区考虑printf("\n示例6: 时区考虑\n");if (clock_gettime(CLOCK_REALTIME, &current_time) == 0) {printf("  UTC时间: %ld.%09ld 秒\n", current_time.tv_sec, current_time.tv_nsec);// 获取本地时区偏移struct tm *utc_tm = gmtime(&current_time.tv_sec);struct tm *local_tm = localtime(&current_time.tv_sec);time_t utc_time = mktime(utc_tm);time_t local_time = mktime(local_tm);long tz_offset = local_time - utc_time;printf("  时区偏移: %+ld 秒\n", tz_offset);}// 示例7: 安全考虑printf("\n示例7: 安全考虑\n");printf("使用clock_settime的安全注意事项:\n");printf("1. 需要适当的权限(CAP_SYS_TIME或root)\n");printf("2. 不当的时间设置可能影响系统稳定性\n");printf("3. 时间跳跃可能影响依赖时间的应用程序\n");printf("4. 应该使用NTP等标准时间同步服务\n");printf("5. 在生产环境中谨慎使用\n\n");// 示例8: 实际应用场景printf("示例8: 实际应用场景\n");// 场景1: NTP客户端printf("场景1: NTP客户端\n");printf("  - 从NTP服务器获取时间\n");printf("  - 调整系统时钟\n");printf("  - 保持时间同步\n\n");// 场景2: 系统初始化printf("场景2: 系统初始化\n");printf("  - 设置初始系统时间\n");printf("  - 从硬件时钟同步\n");printf("  - 恢复时间设置\n\n");// 场景3: 调试和测试printf("场景3: 调试和测试\n");printf("  - 设置特定时间进行测试\n");printf("  - 模拟时间相关场景\n");printf("  - 性能基准测试\n\n");// 场景4: 时间同步服务printf("场景4: 时间同步服务\n");printf("  - 分布式系统时间协调\n");printf("  - 数据库事务时间戳\n");printf("  - 日志时间同步\n\n");// 示例9: 替代方案printf("示例9: 替代方案\n");printf("现代时间管理推荐使用:\n");printf("1. NTP守护进程(ntpd)\n");printf("2. systemd-timesyncd\n");printf("3. chrony\n");printf("4. chronyd\n");printf("5. 避免手动设置系统时间\n\n");printf("总结:\n");printf("clock_settime用于设置系统时钟时间\n");printf("需要适当的权限才能使用\n");printf("主要用于时间同步服务\n");printf("不当使用可能影响系统稳定性\n");printf("推荐使用标准的时间同步服务\n");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/90829.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/90829.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用了Flutter包体积增大就弃用Flutter吗?包体积与开发效率,这两者之间如何权衡?

是否因包体积增大而弃用 Flutter&#xff0c;本质上是 “短期成本&#xff08;包体积&#xff09;” 与 “长期价值&#xff08;跨平台效率、体验一致性等&#xff09;” 的权衡 。这一决策没有绝对答案&#xff0c;需结合项目阶段、用户群体、业务需求等具体场景分析。以下从核…

80道面试经典题目

1.OSI参考模型七层网络协议? 物理层:定义计算机、网络设备、以及直接连接的介质、接口类型的标准,建立比特流的传输,用来组件物理网络的连接。 数据链路层:建立逻辑连接、进行硬件地址寻址,差错校验、差错恢复等功能。 网络层:进行逻辑地址寻址,实现不同网络之间的通…

本周大模型新动向:KV缓存压缩、低成本高性能推理框架、多智能体协作

点击蓝字关注我们AI TIME欢迎每一位AI爱好者的加入&#xff01;01Compress Any Segment Anything Model (SAM)受SAM在零样本分割任务上卓越表现的驱动&#xff0c;其各类变体已被广泛应用于医疗、智能制造等场景。然而&#xff0c;SAM系列模型体量巨大&#xff0c;严重限制了在…

利用frp实现内网穿透功能(服务器)Linux、(内网)Windows

适用于&#xff1a; 本地电脑&#xff08;windows&#xff09;或者Linux(本篇未介绍&#xff09; 工具&#xff1a;FRP&#xff08;fast reverse proxy&#xff09; 系统&#xff1a;Linux、Windows 架构&#xff1a;x86、amd Frp版本&#xff1a;frp_0.62.1_windows_amd64准备…

结合二八定律安排整块时间

你是不是常常感觉一天到晚忙忙碌碌&#xff0c;却总觉得没干成几件“要紧事”&#xff1f;时间仿佛从指缝间溜走&#xff0c;成就感却迟迟不来&#xff1f;其实&#xff0c;高效能人士的秘诀往往藏在最简单的原则里。今天&#xff0c;我们就来聊聊如何巧妙运用“二八定律”&…

波形发生器AWG硬件设计方案

目录 简介 设计需求 设计方案 核心原理图展示 简介 波形发生器是一种数据信号发生器&#xff0c;在调试硬件时&#xff0c;常常需要加入一些信号&#xff0c;以观察电路工作是否正常。用一般的信号发生器&#xff0c;不但笨重&#xff0c;而且只发一些简单的波形&#xff…

11.Dockerfile简介

1.是什么&#xff1f; dockerfile是用来构建镜像的文本文件&#xff0c;是由一条条构建镜像所需的指令和参数构成的脚本。 构建三步骤 编写dockerfile文件docker build命令构建镜像docker run依镜像运行的容器实列 2.dockerfile构建过程解析 1)dockerfile内容的基础知识 …

C# 接口(interface 定义接口的关键字)

目录 使用接口案例 接口继承 练习 定义一个接口&#xff0c;在语法中与定义一个抽象类是没有区别的&#xff0c;但是不允许提供接口中任意成员的实现方式&#xff0c;一般接口只会包含方法 、索引器和事件的声明&#xff0c; 不允许声明成员的修饰符&#xff0c; public都不…

5190 - 提高:DFS序和欧拉序:树上操作(区域修改1)

题目传送门 时间限制 : 2 秒 内存限制 : 256 MB 有一棵点数为 N 的树&#xff0c;以点 1 为根&#xff0c;且树点有边权。然后有 M 个 操作&#xff0c;分为三种&#xff1a; 操作 1 &#xff1a;把某个节点 x 的点权增加 a 。 操作 2 &#xff1a;把某个节点 x 为根的子树中…

【Oracle】数据泵

ORACLE数据库 数据泵 核心参数全解析 ORACLE expdp 命令使用详解 1.ATTACH[schema_name.]job_name Schema_name 用于指定方案名,job_name 用于指定导出作业名.注意,如果使用 ATTACH 选项,在命令行除了连接字符串和 ATTACH 选项外,不能指定任何其他选项,示例如下: expdp hr/hr A…

机器学习的算法有哪些?

&#x1f31f; 欢迎来到AI奇妙世界&#xff01; &#x1f31f; 亲爱的开发者朋友们&#xff0c;大家好&#xff01;&#x1f44b; 我是人工智能领域的探索者与分享者&#xff0c;很高兴在CSDN与你们相遇&#xff01;&#x1f389; 在这里&#xff0c;我将持续输出AI前沿技术、实…

【计算机网络】OSI七层模型

OSI七层模型为什么需要OSI七层模型&#xff1f;OSI七层模型具体是什么&#xff1f;Layer7&#xff1a;应用层&#xff08;Application Layer&#xff09;Layer6&#xff1a;表示层&#xff08;Presentation Layer&#xff09;Layer5&#xff1a;会话层&#xff08;Session Laye…

RS485转Profinet网关配置指南:高效启动JRT激光测距传感器测量模式

RS485转Profinet网关配置指南&#xff1a;高效启动JRT激光测距传感器测量模式RS485转Profinet网关&#xff1a;让JRT激光测距传感器高效开启测量模式在工业自动化场景中&#xff0c;设备间的高效通信是实现精准控制的关键。RS485转Profinet网关作为连接传统RS485设备与现代Prof…

「日拱一码」040 机器学习-不同模型可解释方法

目录 K最近邻(KNN) - 基于距离的模型 决策边界可视化 查看特定样本的最近邻 ​随机森林(RF) - 树模型 feature_importances_ SHAP值分析 可视化单棵树 多层感知器(MLP) - 神经网络 部分依赖图 LIME解释器 权重可视化 支持向量回归(SVR) - 核方法 支持向量可视化 部…

编程与数学 03-002 计算机网络 09_传输层功能

编程与数学 03-002 计算机网络 09_传输层功能一、传输层的作用&#xff08;一&#xff09;进程间通信&#xff08;二&#xff09;提供可靠传输&#xff08;三&#xff09;复用与分用二、TCP协议&#xff08;一&#xff09;TCP的连接建立与释放&#xff08;二&#xff09;TCP的可…

14. Web服务器-Nginx-工作原理

文章目录前言一、简介二、工作原理1. 多进程架构2. 事件驱动模型3. 模块化设计三、工作流程1. 启动阶段2. 等待连接3. 请求处理阶段4. 响应构造与输出5. 连接关闭前言 Nginx‌ Nginx&#xff08;发音为“Engine-X”&#xff09;是一款高性能的开源Web服务器软件&#xff0c;同…

AP-0316:集 USB 即插即用、智能降噪于一体的多功能 AI 声卡,重新定义清晰语音交互

AP-0316突发噪音和抗风噪测试还在为语音设备的噪音刺耳、连接复杂、功放适配麻烦而头疼&#xff1f;AP-0316 多功能 AI 降噪消回音 USB 声卡来了 —— 以 “USB 即插即用 自带功放 智能降噪 场景适配” 四大核心优势&#xff0c;将专业级语音处理技术变得简单易用&#xff0…

Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现卫星图像识别(C#代码,UI界面版)

Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现卫星图像识别&#xff08;C#代码&#xff0c;UI界面版&#xff09;工业相机使用YoloV8模型实现水下鱼类识别工业相机通过YoloV8模型实现卫星图像识别的技术背景在相机SDK中获取图像转换图像的代码分析工业相机图像转换…

某d的评论爬虫学习

本教程仅用于技术研究&#xff0c;请确保遵守目标网站的服务条款。实际使用前应获得官方授权&#xff0c;避免高频请求影响服务器&#xff0c;否则可能承担法律责任。此脚本仅拦截公开评论接口&#xff0c;不涉及用户私密数据。请勿修改代码监听其他请求。分享一下爬某抖评论的…

SQLite 注入:理解与防御

SQLite 注入&#xff1a;理解与防御 引言 随着互联网技术的飞速发展&#xff0c;数据库已成为各类应用程序的核心组成部分。SQLite 作为一款轻量级的关系型数据库&#xff0c;广泛应用于移动应用、桌面应用及嵌入式系统。然而&#xff0c;SQLite 数据库也面临着安全挑战&#x…