黑松山资源网 Design By www.paidiu.com

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

sleep:

普通版本

1、基本设计思路:

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

   3>调"htmlcode">

#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函数使调"htmlcode">

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

sigaction函数可以读取和修改与指定信号相关联的处理动作。调"htmlcode">

int sigemptyset(sigset_t *set); 

函数sigemptyset初始化set所指向的信号集,使其中所有信号的对应bit清零,表"htmlcode">

#include <signal.h>"color: #ff0000">sigsuspend函数与pause函数:都可以将程序挂起,但是sigsuspend函数可以实现对信号屏蔽字的解除与挂起。

sigprocmask

调"htmlcode">

#include <signal.h>"//img.jbzj.com/file_images/article/201706/20176893511849.png" alt="" />

如果调"htmlcode">

#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; 
} 

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

1、设置SIGALRM信号的处理函数;

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

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

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

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

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

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

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

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

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

黑松山资源网 Design By www.paidiu.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
黑松山资源网 Design By www.paidiu.com

P70系列延期,华为新旗舰将在下月发布

3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。

而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?

根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。