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


    在进行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));

    }

     

    2) 基于nanosleep的微秒级封装

    #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协程库中安全使用

    void pollsleep(int milliseconds) {

        (void)poll(NULL, 0, milliseconds);

    }

     

    4) 基于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++标准库提供的:

    5) 毫秒睡眠

    #if __cplusplus >= 201103L

    #include <chrono>

    #include <system_error>

    #include <thread>

     

    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    #endif // __cplusplus >= 201103L

     

    6) 微秒睡眠

    #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

  • 相关阅读:
    Python基本语法_函数属性 & 参数类型 & 偏函数的应用
    8.2.1.10 Nested-Loop Join Algorithms 嵌套循环算法:
    8.2.1.9 LEFT JOIN and RIGHT JOIN Optimization 左关联和又关联
    8.2.1.8 IS NULL Optimization NULL 优化:
    8.2.1.7 Use of Index Extensions 索引扩展适用
    组合索引,索引内过滤
    8.2.1.6 Index Condition Pushdown Optimization 索引条件内推优化
    clustered index和secondary indexes
    101个MySQL调试和优化技巧
    JavaScript 开发的45个经典技巧
  • 原文地址:https://www.cnblogs.com/aquester/p/10321395.html
Copyright © 2020-2023  润新知