在Linux系统编程场景里,进程休眠是经常会用到的功能,usleep和sleep都是实现该功能的常用函数,不过两者的设计目标和特性存在明显差异,合理区分两者才能写出更适配需求的代码。

函数基本定义差异
sleep是C标准库中的函数,定义在<unistd.h>头文件中,它的作用是让当前进程暂停执行指定的秒数。而usleep是早期Unix系统提供的函数,同样定义在<unistd.h>头文件中,设计目标是提供更细粒度的休眠控制,不过在最新的POSIX标准中已经被nanosleep取代,但很多Linux系统仍然保留了对它的支持。
核心参数与精度差异
两者的参数单位和休眠精度是最直观的区别:
- sleep:参数类型为unsigned int,单位是秒,休眠精度通常为秒级,实际休眠时间可能因为系统调度等因素出现偏差,比如传入参数2,进程可能休眠2秒多一点或者略少。
- usleep:参数类型为useconds_t,单位是微秒(1秒=1000000微秒),休眠精度理论上可以达到微秒级,但实际精度受系统时钟频率和调度机制限制,通常只能达到毫秒级左右的精度。
返回值差异
两个函数的返回值含义也有区别:
| 函数名 | 返回值说明 |
|---|---|
| sleep | 返回剩余的休眠秒数,如果休眠正常完成返回0,如果休眠被信号中断,返回未被休眠的剩余秒数 |
| usleep | 成功返回0,失败返回-1,错误原因会设置到errno中,比如传入的参数超过1000000微秒(1秒)时,部分系统会返回错误 |
使用示例对比
sleep使用示例
下面的代码实现让进程休眠3秒后打印提示信息:
#include <stdio.h>
#include <unistd.h>
int main() {
printf("开始休眠,当前时间:%lun", (unsigned long)time(NULL));
// 休眠3秒
unsigned int remain = sleep(3);
if (remain == 0) {
printf("休眠正常完成,当前时间:%lun", (unsigned long)time(NULL));
} else {
printf("休眠被中断,剩余未休眠秒数:%un", remain);
}
return 0;
}
usleep使用示例
下面的代码实现让进程休眠500毫秒(即500000微秒)后打印提示信息:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
int main() {
printf("开始休眠,当前时间:%lun", (unsigned long)time(NULL));
// 休眠500000微秒,即500毫秒
int ret = usleep(500000);
if (ret == 0) {
printf("休眠正常完成,当前时间:%lun", (unsigned long)time(NULL));
} else {
printf("休眠失败,错误码:%dn", errno);
}
return 0;
}
使用注意事项
- usleep的参数如果超过1000000微秒,在部分Linux系统中会直接返回错误,需要休眠超过1秒的场景更推荐使用sleep或者nanosleep。
- 两个函数都可能被信号中断,编写对休眠时间要求严格的程序时,需要处理中断后的剩余休眠逻辑,避免程序逻辑异常。
- 如果是新的程序开发,需要微秒级休眠的话,更推荐使用POSIX标准定义的nanosleep函数,它的参数精度更高,兼容性也更好,usleep属于遗留接口,后续可能会被逐步淘汰。
- 不要在多线程场景中对休眠时间有过于严格的依赖,系统调度和线程优先级都会影响实际的休眠时长,两者的实际休眠时间都可能存在微小偏差。
总结
简单来说,sleep适合需要秒级休眠的场景,使用简单,兼容性广;usleep适合需要更细粒度休眠的场景,但精度和兼容性有限,新开发程序更推荐用nanosleep替代。开发者需要根据实际的休眠时长需求和精度要求选择合适的函数,同时注意处理异常中断的情况,保证程序的稳定性。