前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux中的sleep、usleep、nanosleep、poll和select

Linux中的sleep、usleep、nanosleep、poll和select

作者头像
黑光技术
修改2020-05-15 11:47:31
7K0
修改2020-05-15 11:47:31
举报
文章被收录于专栏:黑光技术黑光技术

在进行Linux C/C++编程时,可调用的sleep函数有好多个,那么究竟应当调用哪一个了?下表列出了这几个函数间的异同点,可作为参考:

性质

精准度

线程安全

信号安全

sleep

libc库函数

不能和alarm同时使用

有些是基于alarm实现的,所以不能和alarm同时使用

usleep

libc库函数

微秒

-

-

POSIX.1-2001已将usleep标注为废弃,POSIX.1-2008已删除usleep,应当使用nanosleep替代usleep

nanosleep

系统调用

纳秒

不确定

即使被信号中断,也可实现实际睡眠时长不小于参数指定时长

clock_nanosleep

系统调用

纳秒

不确定

区别于nanosleep,可选择为相对或绝对时间,其次是可以选择使用哪个时钟

poll

系统调用

毫秒

在协程库libco中可安全使用,如被信号中断,则实际睡眠时长会小于参数指定的时长

ppoll

系统调用

纳秒

如被信号中断,则实际睡眠时长会小于参数指定的时长

select

系统调用

微秒

即使被信号中断,也可实现实际睡眠时长不小于参数指定时长

pselect

系统调用

纳秒

如被信号中断,则实际睡眠时长会小于参数指定的时长

C/C++常用封装:

1) 基于nanosleep的毫秒级封装

代码语言:javascript
复制
#include <time.h>

void millisleep(uint32_t milliseconds) {
    struct timespec ts = {
        milliseconds / 1000,
        (milliseconds % 1000) * 1000000    };

    while ((-1 == nanosleep(&ts, &ts)) && (EINTR == errno));
}

2) 基于nanosleep的微秒级封装

代码语言:javascript
复制
#include <time.h>void microsleep(uint32_t microseconds) {
    struct timespec ts = {
        microseconds / 1000000,
        (microseconds % 1000000) * 1000    };

    while ((-1 == nanosleep(&ts, &ts)) && (EINTR == errno));
}

3) 基于poll的秒级封装

// 可libco协程库中安全使用

代码语言:javascript
复制
void pollsleep(int milliseconds) {
    (void)poll(NULL, 0, milliseconds);
}

4) 基于select的毫秒级封装

代码语言:javascript
复制
void selectsleep(int milliseconds) {

    struct timeval timeout = {
        milliseconds / 1000,
        (milliseconds % 1000)
    };

    struct timeval old_timeout = { timeout.tv_sec, timeout.tv_usec };

    while (true) {
        (void)select(0, NULL, NULL, NULL, &timeout);
        if (timeout.tv_sec<=0 && timeout.tv_usec<=0)
            break;
    }
}

如果开发环境是C++11或更高版本,则可直接使用C++标准库提供的:

5) 毫秒睡眠

代码语言:javascript
复制
#if __cplusplus >= 201103L
#include <chrono>

#include <system_error>

#include <thread> 
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
#endif // __cplusplus >= 201103L

6) 微秒睡眠

代码语言:javascript
复制
#if __cplusplus >= 201103L
#include <chrono>

#include <system_error>

#include <thread> 
std::this_thread::sleep_for(std::chrono::microseconds(1000));
#endif // __cplusplus >= 201103L

上述介绍的sleep函数均不方便控制它们提前结束,如果需要这种sleep,可基于pthread_cond_timedwait实现,实现可参考CEvent源码:

https://github.com/eyjian/libmooon/blob/master/src/sys/event.cpp

看完本文有收获?请分享给更多人

关注「黑光技术」加星标,关注大数据+微服务

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 黑光技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C/C++常用封装:
    • 1) 基于nanosleep的毫秒级封装
      • 2) 基于nanosleep的微秒级封装
        • 3) 基于poll的秒级封装
          • 4) 基于select的毫秒级封装
            • 5) 毫秒睡眠
              • 6) 微秒睡眠
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档