首先说明结构,linux的sleep函数可以使程序暂停一定的秒数,经过一段时间后自动重新开始动作。
实现构想
设定睡眠的秒数
睡眠(挂起)。
重新开始运转
实现机制
设置睡眠秒数: alarm (使用函数设置需要睡眠的秒数,一段时间后闹钟会向当前过程发送SIGALRM信号。 但是,SIGALRM信号的默认操作是杀死进程,因此必须定制SIGALRM信号。
休眠: pause ) )函数锁定当前进程,在收到信号之前不返回错误。
示例代码:模拟实现sleep使当前进程每2秒打印一次“hello yingyingn”
# include # include # includevoidhandler (intsigno ) /程序在睡眠中不执行任何操作,因此不执行任何自定义处理函数。 {}intmysleep ) inttime ) { sigset_t set; sigemptyset (集; 结构信号动作; 结构信号操作; act.sa_handler=handler; //自定义处理函数act.sa_mask=set; act.sa_flags=0; sigaction(SIGalrm,act,oact ); //捕获报警信号以定制处理操作的alarm (时间); //time秒后向过程发送信号的pause (; //进程int_time=alarm(0; //如果程序被提前唤醒以取消报警sigaction(sigalrm,oact,NULL )//恢复捕获信号的原始状态return _time; (} int main ) ) while(1) (printf ) (helloyingyingn ); mysleep(2; }返回0; }
分析问题
上面的代码看起来可以顺利实现我们需要的结果,但是具有多个执行流是否可以正常工作? 例如,如果在设置报警后,当前进程已切换,并且在切换后报警响起,则当前进程将永远锁定。 所以我们需要优化上面的程序。
.优化方案1 :
屏蔽SIGALRM信号
2 .警报(时间)。
解除SIGALRM信号的屏蔽
4.pause ()。
.优化方案2:1 .屏蔽SIG alrm信号
2 .警报(时间)。
3.pause ()。
解除SIGALRM信号的屏蔽
这两个方案大家可以考虑一下吗? 我应该选哪个?
选择方案
方案1 )进程释放掩码后,与pause ()之间的间隙可能会出现相同的问题,从而导致进程永远挂起。
情景2 )程序锁定后,报警信号被切断,持续未解决状态,程序无法接收信号,过程也保持锁定。 所以不能选择方案2。
对于方案1,可以通过取消阻止和挂起为原子操作来改进我们的问题。
解决问题
如方案1所示,由于时间序列问题导致流程出现问题的情况是竞争条件。 在实现sigsuspend (函数为pause )函数挂起功能的同时,也可以解决竞争条件问题。 sigsuspend ()函数的功能是-“释放信号掩码”-“挂起进程并等待信号”-“运行信号处理函数”-“错误返回”。 因此,sigsuspend ()函数与pause () )函数类似,只有错误返回值。 对程序计时要求严格的程序通常使用sigsuspend ()函数。
优化的程序代码
# include # include # includevoidhandler (intsigno ) intmysleep (int time ) { sigset_t set,oset,susmask; sigemptyset (集; sigaddset(set,SIGALRM ); sigprocmask(SIG_block,set,oset ); 结构信号动作; 结构信号操作; act.sa_handler=handler; act.sa_mask=set; act.sa_flags=0; sigaction(SIGalrm,act,oact ); alarm (时间; susmask=oset; sigdelset (sus掩码,SIGALRM ); sigsuspend (sus掩码; int_time=alarm(0; sigaction(SIGalrm,oact,NULL ); sigprocmask(SIG_block,oset,NULL ); return _time; (} int main ) ) while(1) (printf ) (helloyingyingn ); mysleep(2; }返回0; }
这样就完成了sleep函数的模拟。
程序结果
希望以上是正文的全部内容,对大家的学习有帮助。 另外,我希望你支持很多编剧。