zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Heterogeneity Wins
    Android使用ImageView显示网络图片
    Android OOM的解决方式
    洛谷P3390 【模板】矩阵快速幂
    CF732D. Exams[二分答案 贪心]
    洛谷P3388 【模板】割点
    POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]
    NOI2001|POJ1182食物链[种类并查集 向量]
    HDU3038 How Many Answers Are Wrong[带权并查集]
    NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]
  • 原文地址:https://www.cnblogs.com/aquester/p/10321395.html
Copyright © 2011-2022 走看看