返回顶部
首页 > 资讯 > 操作系统 >linux下如何实现sleep
  • 161
分享到

linux下如何实现sleep

2023-06-09 15:06:56 161人浏览 泡泡鱼
摘要

这篇文章给大家分享的是有关linux下如何实现sleep的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。linux 下实现sleep详解及简单实例sleep:普通版本基本设计思路:   1>

这篇文章给大家分享的是有关linux下如何实现sleep的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

linux 下实现sleep详解及简单实例

sleep:

普通版本

基本设计思路:

   1>注册SIGALRM信号的处理函数;
   2>调用alarm(nsecs)设定闹钟;

   3>调⽤pause等待,内核切换到别的进程运行;

   4>nsecs秒之后,闹钟超时,内核发SIGALRM给这个进程 ;

   5>从内核态返回这个进程的⽤户态之前处理未决信号,发现有SIGALRM信号,其处理函数是sig_alrm;

   6> 切换到用户态执行sig_alrm函数,进⼊sig_alrm函数时SIGALRM信号被⾃动屏蔽,从sig_alrm函数返回SIGALRM信 号⾃动解除屏蔽。然后⾃动执⾏系统调用sigreturn再次进入内核,再返回用户态继续执行进程的主控制流程(main函数调⽤的mysleep函数);

   7>pause函数返回-1,然后调⽤alarm(0)取消闹钟,调⽤sigaction恢复SIGALRM信号以前的处理动作。

2、实现代码

#include<stdio.h> #include<signal.h>  void handler(int signo) {}  int mysleep(int timeout) {   struct sigaction act,oact;   act.sa_handler = handler;   act.sa_flags = 0;   sigemptyset(&act.sa_mask);    sigaction(SIGALRM,&act,&oact);   alarm(timeout);   pause();   int ret = alarm(0);   sigaction(SIGALRM,&oact,NULL);   return ret; }  int main() {   while(1)   {     printf("using musleep!\n");     mysleep(3);   }   return 0; }

相关函数分析:

#include <unistd.h> int pause(void);

pause函数使调⽤进程挂起直到有信号递达。如果信号的处理动作是终⽌进程,则进程终⽌,pause函数没有机会返回;如果信号的处理动作是忽略,则进程继续处于挂起状态,pause不返回;如果信号的处理动作是捕捉,则调⽤了信号处理函数之后pause返回-1,errno设置为EINTR, 所以pause只有出错的返回值 。

sigaction函数

#include <signal.h> int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);

sigaction函数可以读取和修改与指定信号相关联的处理动作。调⽤成功则返回0,出错则返回- 1。 signo是指定信号的编号。若act指针⾮空,则根据act修改该信号的处理动作。若oact指针非 空,则通过oact传出该信号原来的处理动作。 

int sigemptyset(sigset_t *set);

函数sigemptyset初始化set所指向的信号集,使其中所有信号的对应bit清零,表⽰该信号集不包含 任何有效信号。

二、优化版本

所需函数分析

#include <signal.h>
 int sigsuspend(const sigset_t *sigmask);

sigsuspend没有成功返回值,只有执⾏了⼀个信号处理函数之后sigsuspend才返回,返回值为-1,errno设置为EINTR。调⽤sigsuspend时,进程的信号屏蔽字由sigmask参数指定,可以通过指定sigmask来临时解除对某 个信号的屏蔽,然后挂起等待,当sigsuspend返回时,进程的信号屏蔽字恢复为原来的值,如果原来对该信号是屏蔽的,sigsuspend返回后仍然是屏蔽的。
sigsuspend函数与pause函数:都可以将程序挂起,但是sigsuspend函数可以实现对信号屏蔽字的解除与挂起。

sigprocmask

调⽤函数sigprocmask可以读取或更改进程的信号屏蔽字(阻塞信号集)。

#include <signal.h>
 int sigprocmask(int how, const sigset_t *set, sigset_t *oset);

如果oset是⾮空指针,则读取进程的当前信号屏蔽字通过oset参数传出。如果set是⾮空指针,则 更改进程的信号屏蔽字,参数how指⽰如何更改。如果oset和set都是⾮空指针,则先将原来的信号 屏蔽字备份到oset⾥,然后根据set和how参数更改信号屏蔽字。

how的选项意义

linux下如何实现sleep

如果调⽤sigprocmask解除了对当前若⼲个未决信号的阻塞,则在sigprocmask返回前,⾄少将其中⼀个信号递达。

代码实现:

#include<stdio.h> #include<signal.h>  void handler(int signo) {}  int mysleep(int timout) {   struct sigaction act,oact;   sigset_t newmask,oldmask,suspmask;   act.sa_handler = handler;   act.sa_flags = 0;   sigemptyset(&act.sa_mask);    sigaction(SIGALRM,&act,&oact);   sigemptyset(&newmask);   sigaddset(&newmask,SIGALRM);   sigprocmask(SIG_BLOCK,&newmask,&oldmask);    alarm(timout);    suspmask = oldmask;   sigdelset(&suspmask,SIGALRM);   sigsuspend(&suspmask);      int unslept = alarm(0);   sigaction(SIGALRM,&oact,NULL);   sigprocmask(SIG_SETMASK,&oldmask,NULL);   return(unslept); } int main() {   while(1)   {     printf("using musleep!\n");     mysleep(3);   }   return 0; }

优化版本解决了普通版本存在的竞态问题。我们重新审视一下普通版本的时序问题。

设置SIGALRM信号的处理函数;

调用alarm()函数设置闹钟;

内核选取更高优先级的进程来取代当前进程,并且这样的进程很多,同时执行时间又很长;

闹钟超时了,内核发送SIGALRM信号给该进程,并且处于未决状态;

优先级更高的进程结束后,内核要调度回这个进程执⾏。 SIGALRM信号递达,执⾏处理函 数sig_alrm之后再次进⼊内核。

返回这个进程的主控制流程,alarm(nsecs)返回,调⽤pause()挂起等待。

可是现在SIGALRM信号已经被处理,进程会导致错误。

在一个进程运行过程中,因为由于异步,所以可能被其他优先级更高的进程,由于时序问题而引发的错误问题。这样的问题称为竞态问题。

优化版本中,先将设置SIGALRM信号的处理函数,然后将SIGALRM信号进行屏蔽,然后调用alarm()函数设置闹钟,然后调用sigprocmask()函数对SIGALRM信号解除屏蔽然后挂起等待,这样就解决了竞态问题。

感谢各位的阅读!关于“linux下如何实现sleep”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: linux下如何实现sleep

本文链接: https://lsjlt.com/news/256662.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • linux下如何实现sleep
    这篇文章给大家分享的是有关linux下如何实现sleep的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。linux 下实现sleep详解及简单实例sleep:普通版本基本设计思路:   1>...
    99+
    2023-06-09
  • linux 下实现sleep详解及简单实例
    linux 下实现sleep详解及简单实例 sleep: 普通版本 1、基本设计思路: 1>注册SIGALRM信号的处理函数; 2>调用alarm(nsecs)设定闹钟; 3...
    99+
    2022-06-04
    详解 实例 简单
  • Linux的sleep命令如何使用
    今天小编给大家分享一下Linux的sleep命令如何使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。语法sleep&nbs...
    99+
    2023-06-28
  • 如何在linux中使用sleep命令
    如何在linux中使用sleep命令?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。使用权限 : 所有使用者 使用方式 : sleep [--help] [--v...
    99+
    2023-06-13
  • Linux下如何实现用户管理
    这篇文章主要介绍Linux下如何实现用户管理,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!在Linux中,用户的管理分为组和用户两种。这个Windows下也是这个样子,组是一类用户的统称。组和用户的关系是:多对多的关...
    99+
    2023-06-13
  • linux下如何实现定时关机
    这篇文章主要讲解了“linux下如何实现定时关机”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“linux下如何实现定时关机”吧!用crontab命令就可以了,下面看一下它的详细用法。名称 :...
    99+
    2023-06-10
  • Linux下如何实现连接跟踪
    小编给大家分享一下Linux下如何实现连接跟踪,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1 引言连接跟踪是许多网络应用的基础。例如,Kubernetes Se...
    99+
    2023-06-15
  • Linux下如何实现文件切割
    这篇文章主要介绍了Linux下如何实现文件切割,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。linux下文件分割可以通过split命令来实现,可以指定按行数分割和安大小分割两...
    99+
    2023-06-28
  • Linux下如何实现双网卡bonding
    这篇文章给大家分享的是有关Linux下如何实现双网卡bonding的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Linux双网卡绑定实现就是使用两块网卡虚拟成为一块网卡,通俗点讲就是两块网卡具有相同的IP地址而并...
    99+
    2023-06-27
  • 如何实现linux下syslog的使用
    这篇文章的内容主要围绕如何实现linux下syslog的使用进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!syslog 系统日志应用 1)...
    99+
    2023-06-28
  • nodejs中实现sleep功能实例
    nodejs最让人不爽的就是其单线程特性,很多事情没法做,对CPU密集型的场景,性能也不够强劲。很长一段时间,我想在javascript语言框架下寻求一些解决方案,解决无法操作线程、性能差的问题。曾经最让我...
    99+
    2022-06-04
    实例 功能 nodejs
  • 如何实现linux下socket文件传输
    这期内容当中小编将会给大家带来有关如何实现linux下socket文件传输,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。什么是 socket?socket 的原意是“插座”,在计算机通信领域,socket...
    99+
    2023-06-28
  • Linux 下 PHP 如何实现异步编程?
    随着互联网的迅速发展,越来越多的网站和应用程序需要处理大量的请求和数据,这就要求我们的代码能够快速响应用户请求,并且能够高效地处理数据。而异步编程技术正是为了满足这一需求而出现的。 那么,什么是异步编程呢?简单来说,异步编程就是在程序运行...
    99+
    2023-09-12
    npm 异步编程 linux
  • Linux下如何实现网络故障诊断
    这篇文章将为大家详细讲解有关Linux下如何实现网络故障诊断,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。网卡故障可以分为硬件故障和软件故障,判断硬件故障最简单的方法是把该网卡插到其它计算机上使用,如果还...
    99+
    2023-06-12
  • Linux系统下如何实现用户审计
    这篇文章主要讲解了“Linux系统下如何实现用户审计”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux系统下如何实现用户审计”吧!创建审计日志目录 代码如下:mkdir -p...
    99+
    2023-06-12
  • 如何实现linux系统下安全管理
    这篇文章主要介绍“如何实现linux系统下安全管理”,在日常操作中,相信很多人在如何实现linux系统下安全管理问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何实现linux系统下安全管理”的疑惑有所帮助!...
    99+
    2023-06-10
  • linux系统下如何实现用户管理
    这篇文章将为大家详细讲解有关linux系统下如何实现用户管理,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、用户及用户组存在的意义1)用户存在的意义系统的资源是有限的,如何合理分配系统资源?身份 acc...
    99+
    2023-06-21
  • Linux下如何实现变量替换技术
    这篇文章主要介绍了Linux下如何实现变量替换技术,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1.1.1  ${value:-word}如果变量value没有定义...
    99+
    2023-06-28
  • 如何使用Ticker Or Sleep
    本篇内容介绍了“如何使用Ticker Or Sleep”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在写 Python 的时候,如果想让某个...
    99+
    2023-06-15
  • linux下如何实现快速拷贝大文件
    拷贝数据 远程拷贝数据的时候,我们一般使用rsync命令,但是如果拷贝大量的小文件,会导致rsync的传输速度慢。使用tar pv lz4打包压缩传输,可以解决这问题,使用这个方法,等同于使用scp、rsync传输...
    99+
    2022-06-03
    linux 快速拷贝 大文件
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作