关于sleep,usleep,time,clock函数使用总结(linux环境)

本文详细介绍了Linux环境下sleep、usleep、time及clock函数的使用方法。sleep与usleep用于进程挂起,分别以秒和微秒为单位;time函数记录自1970年以来的秒数;clock函数则测量CPU时间。通过实例代码展示了如何应用这些函数并计算时间差。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于sleep,usleep,time,clock函数使用总结(linux环境)

各个函数的使用介绍

  • sleep、usleep函数在头文件 #include <unistd.h> 里面,sleep函数是让进程挂起xx秒,usleep函数是让进程挂起xx微秒。

sleep(5) ; //进程挂起5秒
usleep(1000000); //进程挂起1秒,也就是1百万微秒

  • time函数是个C语言函数,在头文件 #include <time.h> 里面,返回从1970年:0时:0分:0秒到调用该函数时候积累的秒数。

time_t time(time_t * timer); //函数原型
time_t timer1 = time(NULL); //获取到当前秒数的方法一
time_t timer2;
time(&timer2); // 获取到当年秒数的方法二

  • clock函数返回的cpu消耗的时间,进程挂起的时间不算在内,返回的数要除上CLOCKS_PER_SEC才能得到真实的秒数

clock_t clock(void); //函数原型

程序实验代码

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

int main()
{
    time_t beg,end;
    clock_t cb,ce;
    cb = clock();
    beg = time(NULL);
    sleep(5);
    ce = clock();
    end = time(NULL);
    printf("%ld %ld %ld  %lf\n",cb,ce,CLOCKS_PER_SEC,(double)(ce-cb)/CLOCKS_PER_SEC);
    printf("%ld %ld %lf\n",beg,end,difftime(end,beg));
    beg = time(NULL);
    usleep(1000000);
    end = time(NULL);
    printf("%ld %ld %lf\n",beg,end,difftime(end,beg));
    return 0;
}

程序结果

在这里插入图片描述

<think>嗯,用户之前问了关于Linux线程如何屏蔽实时信号的问题,现在又遇到了在main函数的循环sleep不起作用的情况。我需要先理解用户的具体问题是什么。用户提到在main函数的循环中使用sleep,但似乎没有效果,也就是说程序可能没有按预期暂停执行。这可能有很多原因,我需要逐一分析。 首先,用户可能是在多线程环境使用sleep,或者是在信号处理函数中被中断。比如,如果程序有信号处理函数,而sleep被信号中断后没有正确处理,导致循环继续执行,看起来像是sleep没起作用。这时候应该检查是否处理了EINTR错误,或者在信号处理函数中是否有影响sleep的逻辑。 其次,用户可能误解了sleep的行为。sleep函数会让当前线程休眠指定的秒数,但如果有其他线程在运行,或者程序中有异步操作,可能会让用户感觉sleep没有生效。比如,如果主线程在sleep,而另一个线程在运行,用户可能看到程序继续执行,但实际上主线程确实休眠了。 另外,用户可能混淆了sleepusleep函数的用法,或者使用了错误的头文件,导致编译错误或者函数行为不符合预期。需要检查代码中的函数调用是否正确,是否包含了正确的头文件,比如<unistd.h>。 还有一种情况是,程序可能被外部因素干扰,比如系统负载过高,导致sleep的时间不准确,但这通常不会导致sleep完全不起作用,只是时间上有些偏差。或者用户可能在循环中有其他代码,比如非阻塞的操作,导致即使sleep了,循环仍然快速执行。 我需要考虑用户可能的代码结构,比如是否在循环中调用了sleep,但循环体内有其他代码执行时间过长,导致每次循环的总时间超过预期。例如,如果循环有一个执行10秒的操作,然后sleep(1),整个循环周期会是11秒,而不是用户期望的1秒。这时候用户可能会误以为sleep没起作用,但实际上是因为其他代码耗时过长。 另外,用户可能没有正确处理sleep的返回值。当sleep被信号中断时,它会返回剩余的秒数,如果不处理这个返回值,直接继续执行,可能导致休眠时间不足。正确的做法是循环调用sleep直到返回0,或者在信号处理函数中设置标志位,避免重复中断。 也有可能用户的环境存在特殊配置,比如实时内核或某些调度策略,影响了sleep的行为。这种情况下,可能需要检查系统的调度策略或使用更精确的休眠函数,如nanosleep。 综合这些可能性,我需要组织一个清晰的回答,覆盖常见原因,并提供示例代码和解决方案。需要分点说明可能的原因,每种原因对应的现象和解决方法,这样用户可以根据自己的情况逐一排查。同时,要提醒用户检查信号处理、多线程、代码逻辑等方面的问题,并提供代码示例说明正确的处理方式。</think>在 Linux 中,如果在 `main` 函数的循环中调用 `sleep` 函数却未按预期休眠(例如循环立即重复执行或休眠时间异常),可能是由以下原因导致的: --- ### **1. 常见原因分析** #### **(1) 信号中断(关键原因)** - **现象**:`sleep` 被信号中断,提前结束休眠。 - **机制**: - `sleep` 函数在休眠期间若收到未被阻塞(屏蔽)的信号,会立即返回剩余的休眠时间(秒数)。 - 若未正确处理中断,循环会快速重复执行。 - **验证方法**: 打印 `sleep` 的返回值(剩余未休眠的秒数),观察是否非零: ```c unsigned int remaining = sleep(5); printf("sleep interrupted, remaining: %u\n", remaining); // 若输出非0,说明被信号中断 ``` #### **(2) 多线程或异步操作** - **现象**:主线程休眠时,其他线程或异步任务仍在运行,导致看似未休眠。 - **示例**: ```c void* thread_task(void* arg) { while (1) { printf("Background thread running...\n"); } return NULL; } int main() { pthread_t tid; pthread_create(&tid, NULL, thread_task, NULL); while (1) { sleep(1); // 主线程休眠,但子线程仍在输出 printf("Main thread wakes up\n"); } return 0; } ``` #### **(3) 代码逻辑问题** - **现象**:循环内其他操作耗时较长,掩盖了 `sleep` 的效果。 - **示例**: ```c while (1) { do_time_consuming_work(); // 假设此函数耗时10秒 sleep(1); // 总循环周期为 10+1=11 秒,而非预期的1秒 } ``` --- ### **2. 解决方法** #### **(1) 处理信号中断** - **重启休眠**:在信号中断后,继续完成剩余的休眠时间。 ```c unsigned int sleep_duration = 5; while (sleep_duration > 0) { sleep_duration = sleep(sleep_duration); } ``` - **屏蔽信号**:若需彻底避免中断,可阻塞相关信号。 ```c #include <signal.h> sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGINT); // 例如屏蔽 SIGINT pthread_sigmask(SIG_BLOCK, &mask, NULL); sleep(5); // 此时不会被 SIGINT 中断 ``` #### **(2) 使用更精确的休眠函数** - **`nanosleep`**:支持纳秒级休眠,且可配置是否被信号中断。 ```c #include <time.h> struct timespec req = { .tv_sec = 1, .tv_nsec = 0 }; // 休眠1秒 struct timespec rem; while (nanosleep(&req, &rem) == -1 && errno == EINTR) { req = rem; // 若被信号中断,继续剩余时间 } ``` #### **(3) 检查代码逻辑** - **测量实际耗时**:使用 `clock_gettime` 验证循环周期。 ```c #include <time.h> struct timespec start, end; while (1) { clock_gettime(CLOCK_MONOTONIC, &start); // ... 执行代码 ... sleep(1); clock_gettime(CLOCK_MONOTONIC, &end); double elapsed = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9; printf("Actual elapsed time: %.2f seconds\n", elapsed); } ``` --- ### **3. 完整示例(处理信号中断)** ```c #include <stdio.h> #include <unistd.h> #include <signal.h> #include <errno.h> // 信号处理函数 void sigint_handler(int signo) { printf("Received SIGINT\n"); } int main() { // 注册信号处理 signal(SIGINT, sigint_handler); while (1) { unsigned int remaining = sleep(5); if (remaining > 0) { printf("sleep interrupted, remaining: %u seconds\n", remaining); } else { printf("sleep completed\n"); } } return 0; } ``` --- ### **4. 注意事项** - **信号安全函数**:在信号处理函数中避免调用非异步安全函数(如 `printf`)。 - **多线程同步**:若涉及多线程,需使用锁或条件变量控制并发逻辑。 - **系统负载**:高负载场景下,休眠时间可能有微小误差(通常可忽略)。 --- 通过以上方法,可以准确定位并解决 `sleep` 在循环中“不生效”的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值