我是靠谱客的博主 腼腆发卡,最近开发中收集的这篇文章主要介绍APUE编程:85---信号处理(休眠函数:sleep、usleep、nanosleep、clock_nanosleep)一、sleep函数二、usleep函数三、nanosleep函数四、clock_nanosleep函数,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、sleep函数

#include <unistd.h>
unsigned int sleep(unsigned int seconds);
  • 功能:sleep函数使进程被挂起,休眠参数所指定的秒数
  • 直到满足下面两个条件之一才返回:
    • ①已经过了参数seconds所指定的时间。此种情况函数返回0
    • ②调用进程捕捉到一个信号并从信号处理程序返回。此种情况函数返回sleep未休眠完的秒数
  • 如同alarm一样,由于其他系统活动,实际返回时间比所要求的会迟一些
  • 参数:秒数
  • 返回值:
    • 成功休眠指定的秒数:返回0
    • 如果在休眠的过程中被信号处理程序中断:返回未休眠的秒数

sleep和其他时间函数混合使用会如何?

  • 尽管sleep可以用alarm函数(参阅:https://blog.csdn.net/qq_41453285/article/details/89218980)实现,但这并不是必需的
  • 如果使用alarm,则这两个函数之间可能相互影响。POSIX.1标准对这些交互作用并未作任何说明
  • 例如,若先调用alarm(10),过了3秒后又调用sleep(5),那么将如何呢? sleep将在5秒后返回(假定在这段时间内没有捕捉到另一个信号),但是否在2秒后又产生另一个SIGALRM信号呢?这种细节依赖于具体实现

演示案例

  • 下面是一个POSIX.1 sleep函数的实现
  • 下面的函数是在讲解alarm时案例的修改版,它可以可靠地处理信号,避免了早期实现中的竞争问题,但是仍未处理与以前设置的闹钟的交互作用
  • 下面的代码没有使用任何形式的非局部转移(如介绍alarm函数时为了避免alarm与pause之间的竞争条件所做的那样),所以对处理SIGALRM信号期间可能执行的其它信号处理程序没有任何影响
static void sig_alrm(int signo)
{
    /* nothing to do, just returning wakes up sigsuspend() */
}

unsigned int sleep(unsigned int seconds)
{
    struct sigaction newact, oldact;
    sigset_t newmask, oldmask, suspmask;
    unsigned int unslept;

    /* set our handler, save previous information */
    newact.sa_handler = sig_alrm;
    sigemptyset(&newact.sa_mask);
    newact.sa_flags = 0;
    sigaction(SIGALRM, &newact, &oldact);

    /* block SIGALRM and save current signal mask */
    sigemptyset(&newmask);
    sigaddset(&newmask, SIGALRM);
    sigprocmask(SIG_BLOCK, &newmask, &oldmask);
    alarm(seconds);
    suspmask = oldmask;

    /* make sure SIGALRM isn’t blocked */
    sigdelset(&suspmask, SIGALRM);

    /* wait for any signal to be caught */
    sigsuspend(&suspmask);

    /* some signal has been caught, SIGALRM is now blocked */
    unslept = alarm(0);

    /* reset previous action */
    sigaction(SIGALRM, &oldact, NULL);

    /* reset signal mask, which unblocks SIGALRM */
    sigprocmask(SIG_SETMASK, &oldmask, NULL);
    return(unslept);
}

二、usleep函数

#include <unistd.h>
int usleep(useconds_t usec);
  • 功能:usleep函数使进程被挂起,休眠参数所指定的微秒
  • 睡眠可能会因任何系统活动或处理调用所花费的时间或系统计时器的粒度而略微延长
  • 参数:微秒数
  • 返回值: 
    • 成功:返回0
    • 错误:返回-1,并设置对应的errno值:
      • EINTR:被信号中断
      • EINVAL:usec大于或等于1000000

三、nanosleep函数

#include <time.h>
int nanosleep(const struct timespec *reqtp, struct timespec *remtp);
  • 功能:与sleep功能相似,nanosleep提供纳秒级的精度 
  • 参数:
    • 参数1:要休眠的时间(纳秒)
    • 参数2:如果某个信号中断了休眠,进程并没有终止,remtp指向的timespec结构就会被设置为未休眠完的时间长度。如果不想保存,可以设置为NULL
  • 返回值:
    • 成功休眠到要求的时间:返回0
    • 出错:返回-1
  • struct timespec结构如下:
struct timespec {
    time_t tv_sec;   //秒
    long   tv_nsec;  //纳秒,字段的值必须在0到999999999之间
};

特点

  • 这个函数挂起进程,直到要求的时间已经超时或者某个信号中断了该函数
  • 如果系统并不支持纳秒这一精度,要求的时间就会取整
  • 因为nanosleep函数并不设计产生任何信号,所以不需要担心与其他函数的交互

四、clock_nanosleep函数

#include <time.h>
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *reqtp, struct timespec *remtp);
  • 功能:高分辨率睡眠与特定时钟
  • 返回值:
    • 休眠完指定的时间:返回0
    • 如果调用被信号处理程序中断或遇到错误:则返回下面的错误之一:
      • EFAULT:请求或保持指定的无效地址
      • EINTR:睡眠被信号处理器中断
      • EINVAL:tv_nsec字段中的值不在0到999999999的范围内,或者tv_sec为负数
      • EINVAL:clock_id是无效的(CLOCK_THREAD_CPUTIME_ID不允许使用clock_id值)

clock_id参数

  • clock_id指定了计算延迟时间基于的时钟,标识符如下

flags参数

  • flags参数用于控制延迟是相对的还是绝对的
  • 可取的值如下:
    • flags为0:表示休眠时间是相对的(例如,希望休眠的时间长度)
    • flags为TIMER_ABSTIME:休眠时间是绝对的(例如,希望休眠到时钟到达某个特定的时间)

reqtp和temtp参数

  • reqtp和temtp参数与nanosleep函数中的相同
  • 使用绝对时间时,remtpp参数未使用,因为没必要
  • 在时钟到达指定的绝对时间值以前,可以为其他的clock_nanosleep调用复用reqtp参数相同的值

注意事项

  • 除了出错返回:调用clocl_nanosleep(CLOCK_REALTIME,0,reqtp,remtp);和调用nanosleep(reqtp,remtp);效果相同

最后

以上就是腼腆发卡为你收集整理的APUE编程:85---信号处理(休眠函数:sleep、usleep、nanosleep、clock_nanosleep)一、sleep函数二、usleep函数三、nanosleep函数四、clock_nanosleep函数的全部内容,希望文章能够帮你解决APUE编程:85---信号处理(休眠函数:sleep、usleep、nanosleep、clock_nanosleep)一、sleep函数二、usleep函数三、nanosleep函数四、clock_nanosleep函数所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部