美文网首页
Linux中的sleep、usleep、nanosleep、po

Linux中的sleep、usleep、nanosleep、po

作者: CarlosHu | 来源:发表于2020-03-03 12:02 被阅读0次

    在进行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的毫秒级封装
    #include <time.h>
    void millisleep(uint32_t milliseconds) {
        struct timespec ts = {
            milliseconds / 1000,
            (milliseconds % 1000) * 1000000
        };
        while ((-1 == nanosleep(&ts, &ts)) && (EINTR == errno));
    }
    
    1. 基于nanosleep的微秒级封装
    #include <time.h>
    void microsleep(uint32_t microseconds) {
        struct timespec ts = {
            microseconds / 1000000,
            (microseconds % 1000000) * 1000
        };
        while ((-1 == nanosleep(&ts, &ts)) && (EINTR == errno));
    }
    
    1. 基于poll的秒级封装
    // 可libco协程库中安全使用
    void pollsleep(int milliseconds) {
        (void)poll(NULL, 0, milliseconds);
    }
    
    1. 基于select的毫秒级封装
    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++标准库提供的:

    1. 毫秒睡眠
    #if __cplusplus >= 201103L
    #include <chrono>
    #include <system_error>
    #include <thread>
     
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    #endif // __cplusplus >= 201103L
    
    1. 微秒睡眠
    #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

    转自:https://blog.csdn.net/aquester/article/details/86651206

    相关文章

      网友评论

          本文标题:Linux中的sleep、usleep、nanosleep、po

          本文链接:https://www.haomeiwen.com/subject/utyqlhtx.html