【Linux】延时函数sleep、usleep、nanosleep、select、pselect的比较

2024-05-08 05:18

本文主要是介绍【Linux】延时函数sleep、usleep、nanosleep、select、pselect的比较,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、简介

sleep()-------以秒为单位
#include<unistd.h>
unsigned int sleep(unsigned int seconds);
return:若进程暂停到参数seconds 所指定的时间,成功则返回0,若有信号中断则返回剩余秒数。
在linux中,sleep是通过nanosleep实现的。在一些其他系统中(例如POSIX.1),它是通过alarm()来实现的。

usleep()----以微秒为单位
#include<unistd.h>
unsigned int usleep(unsigned int useconds);
return:若进程暂停到参数seconds 所指定的时间,成功则返回0,若有信号中断则返回剩余微秒数。

nanosleep( )---------以纳秒为单位
#include<time.h>
struct timespec
{
time_t tv_sec; /* 秒seconds /
long tv_nsec; /
纳秒nanoseconds */
};
int nanosleep(const struct timespec req, struct timespec rem);
return: 若进程暂停到参数
req所指定的时间,成功则返回0,若有信号中断则返回-1,并且将剩余微秒数记录在
rem中。
req->tv_sec是以秒为单位,而tv_nsec以毫微秒为单位(10的-9次方秒)。
由于调用nanosleep是是进程进入TASK_INTERRUPTIBLE,这种状态是会相应信号而进入TASK_RUNNING状态的。

2、注意

使用这些函数时一定要注意判断返回值。有时候会出现sleep函数被系统中断的情况,导致结果不符合预期。
while (nanosleep(&ts, &ts) == -1 && errno == EINTR) {}

3、精确度对比

低精度情况(100000us及以上):usleep和nanosleep表现差不多。select和pselect表现较差。
高精度情况(100000us及以上):四者表现差不多。
fuction time(usec) realtime reduce

----------------------------------------------------usleep         500000     500091         91nanosleep      500000     500089         89select         500000     500540        540pselect        500000     500549        549
--------------------------------usleep         100000     100078         78nanosleep      100000     100110        110select         100000     100157        157pselect        100000     100149        149
--------------------------------usleep          50000      50091         91nanosleep       50000      50107        107select          50000      50111        111pselect         50000      50084         84
--------------------------------usleep          10000      10086         86nanosleep       10000      10091         91select          10000      10089         89pselect         10000      10088         88
--------------------------------usleep           1000       1089         89nanosleep        1000       1065         65select           1000       1065         65pselect          1000       1066         66
--------------------------------usleep            900        969         69nanosleep         900        974         74select            900        970         70pselect           900        980         80
--------------------------------usleep            500        569         69nanosleep         500        565         65select            500        569         69pselect           500        569         69
--------------------------------usleep            100        166         66nanosleep         100        165         65select            100        163         63pselect           100        163         63
--------------------------------usleep             10         73         63nanosleep          10         76         66select             10         73         63pselect            10         78         68
--------------------------------usleep              1         64         63nanosleep           1         66         65select              1         65         64pselect             1         63         62
--------------------------------
4、测试代码
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<sys/time.h>
#include<errno.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/select.h>int main(int argc, char **argv)
{unsigned int nTimeTestSec = 0;unsigned int nTimeTest = 0;struct timeval tvBegin;struct timeval tvNow;int ret = 0;unsigned int nDelay = 0;struct timeval tv;int fd = 1;int i = 0;struct timespec req;unsigned int delay[20] = {500000, 100000, 50000, 10000, 1000, 900, 500, 100, 10, 1, 0};int nReduce = 0; //误差fprintf(stderr, "%19s%12s%12s%12s\n", "fuction", "time(usec)", "realtime", "reduce");fprintf(stderr, "----------------------------------------------------\n");for (i = 0; i < 20; i++){if (delay[i] <= 0)break;nDelay = delay[i];//test sleepgettimeofday(&tvBegin, NULL);ret = usleep(nDelay);if(ret == -1){fprintf(stderr, "usleep error, errno=%d [%s]\n", errno, strerror(errno));}gettimeofday(&tvNow, NULL);nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;nReduce = nTimeTest - nDelay;fprintf (stderr, "\t usleep       %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);//test nanosleepreq.tv_sec = nDelay/1000000;req.tv_nsec = (nDelay%1000000) * 1000;gettimeofday(&tvBegin, NULL);ret = nanosleep(&req, NULL);if (-1 == ret){fprintf (stderr, "\t nanousleep   %8u   not support\n", nDelay);}gettimeofday(&tvNow, NULL);nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;nReduce = nTimeTest - nDelay;fprintf (stderr, "\t nanosleep    %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);//test selecttv.tv_sec = 0;tv.tv_usec = nDelay;gettimeofday(&tvBegin, NULL);ret = select(0, NULL, NULL, NULL, &tv);if (-1 == ret){fprintf(stderr, "select error. errno = %d [%s]\n", errno, strerror(errno));}gettimeofday(&tvNow, NULL);nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;nReduce = nTimeTest - nDelay;fprintf (stderr, "\t select       %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);//pselcetreq.tv_sec = nDelay/1000000;req.tv_nsec = (nDelay%1000000) * 1000;gettimeofday(&tvBegin, NULL);ret = pselect(0, NULL, NULL, NULL, &req, NULL);if (-1 == ret){fprintf(stderr, "select error. errno = %d [%s]\n", errno, strerror(errno));}gettimeofday(&tvNow, NULL);nTimeTest = (tvNow.tv_sec - tvBegin.tv_sec) * 1000000 + tvNow.tv_usec - tvBegin.tv_usec;nReduce = nTimeTest - nDelay;fprintf (stderr, "\t pselect      %8u   %8u   %8d\n", nDelay, nTimeTest,nReduce);fprintf (stderr, "--------------------------------\n");}return 0;
}

参考博客:https://www.jianshu.com/p/42abcc2c9e50

这篇关于【Linux】延时函数sleep、usleep、nanosleep、select、pselect的比较的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/969408

相关文章

基于Linux的ffmpeg python的关键帧抽取

《基于Linux的ffmpegpython的关键帧抽取》本文主要介绍了基于Linux的ffmpegpython的关键帧抽取,实现以按帧或时间间隔抽取关键帧,文中通过示例代码介绍的非常详细,对大家的学... 目录1.FFmpeg的环境配置1) 创建一个虚拟环境envjavascript2) ffmpeg-py

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

详解Linux中常见环境变量的特点与设置

《详解Linux中常见环境变量的特点与设置》环境变量是操作系统和用户设置的一些动态键值对,为运行的程序提供配置信息,理解环境变量对于系统管理、软件开发都很重要,下面小编就为大家详细介绍一下吧... 目录前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变

Linux系统中的firewall-offline-cmd详解(收藏版)

《Linux系统中的firewall-offline-cmd详解(收藏版)》firewall-offline-cmd是firewalld的一个命令行工具,专门设计用于在没有运行firewalld服务的... 目录主要用途基本语法选项1. 状态管理2. 区域管理3. 服务管理4. 端口管理5. ICMP 阻断

Linux实现线程同步的多种方式汇总

《Linux实现线程同步的多种方式汇总》本文详细介绍了Linux下线程同步的多种方法,包括互斥锁、自旋锁、信号量以及它们的使用示例,通过这些同步机制,可以解决线程安全问题,防止资源竞争导致的错误,示例... 目录什么是线程同步?一、互斥锁(单人洗手间规则)适用场景:特点:二、条件变量(咖啡厅取餐系统)工作流

Linux中修改Apache HTTP Server(httpd)默认端口的完整指南

《Linux中修改ApacheHTTPServer(httpd)默认端口的完整指南》ApacheHTTPServer(简称httpd)是Linux系统中最常用的Web服务器之一,本文将详细介绍如何... 目录一、修改 httpd 默认端口的步骤1. 查找 httpd 配置文件路径2. 编辑配置文件3. 保存

Linux使用scp进行远程目录文件复制的详细步骤和示例

《Linux使用scp进行远程目录文件复制的详细步骤和示例》在Linux系统中,scp(安全复制协议)是一个使用SSH(安全外壳协议)进行文件和目录安全传输的命令,它允许在远程主机之间复制文件和目录,... 目录1. 什么是scp?2. 语法3. 示例示例 1: 复制本地目录到远程主机示例 2: 复制远程主