各位老铁们好,相信很多人对LINUX下实现睡眠都不是特别的了解,因此呢,今天就来为大家分享下关于LINUX下实现睡眠以及的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!
1、注册SIGALRM信号的处理函数;
2调用alarm(nsecs)设置闹钟;
3、调用pause等待,内核切换到另一个进程运行;
4nsecs秒后,警报超时,内核向进程发送SIGALRM;
5. 在从内核态返回到该进程的用户态之前处理挂起的信号。发现有SIGALRM信号,其处理函数为sig_alrm;
6.切换到用户模式并执行sig_alrm函数。进入sig_alrm函数时会自动屏蔽SIGALRM信号。从sig_alrm 函数返回时,SIGALRM 信号会自动取消屏蔽。然后自动执行系统调用sigreturn再次进入内核,然后返回到用户态继续执行进程的主控制流程(main函数调用的mysleep函数);
7pause函数返回-1,然后调用alarm(0)取消报警,调用sigaction恢复之前SIGALRM信号的处理动作。
2. 实现代码
[cpp] 查看纯文本
#includesignal.h
无效处理程序(int Signo)
{}
int mysleep(int 超时)
{
结构sigaction act,oact;
act.sa_handler=处理程序;
act.sa_flags=0;
sigemptyset(act.sa_mask);
sigaction(SIGALRM,act,oact);
报警(超时);
暂停();
int ret=警报(0);
sigaction(SIGALRM,oact,NULL);
返回ret;
}
int main()
{
同时(1)
{
printf(‘使用musleep!\n’);
我的睡眠(3);
}
返回0;
}
相关函数分析:
[cpp] 查看纯文本
int 暂停(无效);
暂停函数使调用进程暂停,直到传递信号为止。如果信号处理动作是终止进程,则进程终止,pause函数没有机会返回;如果信号处理动作是忽略,则进程继续处于挂起状态并且pause不会返回;如果信号处理动作是捕获,那么调用信号处理函数后,pause返回-1,并且errno设置为EINTR,所以pause只返回错误值。
信号动作函数
[cpp] 查看纯文本#include signal.h
int sigaction(int Signo, conststruct sigaction *act, struct
sigaction *oact);
sigaction函数可以读取和修改与指定信号相关的处理动作。如果调用成功,将返回0,如果发生错误,将返回-1。 Signo 是指定信号的编号。如果act指针不为空,则根据act修改信号处理动作。如果oact指针不为空,则通过oact发送信号的原始处理动作。
[cpp] 查看纯文本
int sigemptyset(sigset_t *set);
函数sigemptyset初始化set指向的信号集,并清除其中所有信号的相应位,表明该信号集不包含任何有效信号。
2.优化版本
所需功能分析
[cpp] 查看纯文本
int sigsuspend(const sigset_t *sigmask);
sigsuspend 未成功返回值。 SigSuspend 仅在执行信号处理函数后返回。返回值为-1,errno 设置为EINTR。当sigsuspend被调用时,进程的信号掩码由sigmask参数指定。您可以通过指定sigmask 来暂时解除对某个信号的阻塞,然后挂断并等待。当sigsuspend返回时,进程的信号掩码恢复到原来的值。如果信号本来是被屏蔽的,那么sigsuspend返回后仍然会被屏蔽。
sigSuspend函数和pause函数:都可以暂停程序,但sigSuspend函数可以释放并暂停信号掩码字。
sigproc掩码
调用函数sigprocmask可以读取或改变进程的信号掩码(阻塞信号集)。
[cpp] 查看纯文本
#包括信号.h
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
如果oset是非空指针,则通过oset参数传出当前读取过程的信号掩码字。如果set是非空指针,则改变进程的信号掩码,参数how表示如何改变。如果oset和set都是非空指针,则先将原来的信号掩码备份到oset,然后根据set和how参数更改信号掩码。
how选项的含义
如果调用sigprocmask 取消阻止任何当前待处理的信号,则在sigprocmask 返回之前至少会传递其中一个信号。
代码实现:
[cpp] 查看纯文本
#includestdio.h
#includesignal.h
无效处理程序(int Signo)
{}
int mysleep(int 超时)
{
结构sigaction act,oact;
sigset_t 新掩码、旧掩码、suspmask;
act.sa_handler=处理程序;
act.sa_flags=0;
sigemptyset(act.sa_mask);
sigaction(SIGALRM,act,oact);
sigemptyset(newmask);
sigaddset(newmask,SIGALRM);
sigprocmask(SIG_BLOCK,新掩码,旧掩码);
报警(超时);
suspmask=旧掩码;
sigdelset(suspmask,SIGALRM);
sigsuspend(suspmask);
int 未睡眠=闹钟(0);
sigaction(SIGALRM,oact,NULL);
sigprocmask(SIG_SETMASK,oldmask,NULL);
返回(未睡);
}
int main()
{
同时(1)
{
printf(‘使用musleep!\n’);
我的睡眠(3);
}
返回0;
}
优化版本解决了普通版本存在的竞争条件问题。我们重新审视一下普通版的时序问题。
1、设置SIGALRM信号的处理函数;
2、调用alarm()函数设置闹钟;
3、内核选择一个优先级较高的进程来替换当前进程,而且这样的进程很多,执行时间也很长;
4、闹钟超时,内核向进程发送SIGALRM信号,进程处于挂起状态;
5. 当优先级较高的进程结束后,内核会将其调度回来执行。 SIGALRM信号下发,执行处理函数sig_alrm,然后再次进入内核。
6.返回本流程主控制流程,alarm(nsecs)返回,并调用pause()等待。
7. 但是现在SIGALRM信号已经被处理了,这个过程会导致错误。
在进程运行过程中,由于异步特性,可能会因为时序问题而导致其他优先级较高的进程出现错误。此类问题称为竞争条件。
原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/113452.html
用户评论
纯情小火鸡
突然发现自己用的linux指令真的太少了!这篇博客终于教会我了如何使用sleep命令了,之前总是不知道该用什么代替Windows那个睡醒的功能。现在可以写一些定时任务了
有18位网友表示赞同!
生命一旅程
这篇文章写得太简单了吧,像是在讲给小朋友听的感觉… 我希望能看到一些更复杂的用法,比如在循环中使用sleep,或者结合其他工具实现更高级的定时功能。
有17位网友表示赞同!
心已麻木i
终于明白为什么有些人总是说linux才是真正的自由操作系统!自带这么强大的实用工具,还能玩出这么多花样!感谢作者分享这篇文章!
有12位网友表示赞同!
三年约
我一直都用的是Python里的time模块来实现睡眠效果,没想到Linux下还有专门的sleep命令可以用。感觉这个commands really makes things simpler
有6位网友表示赞同!
凉凉凉”凉但是人心
我这里好像有点问题啊,一直运行sleep指令就停在那不动了… 可能是我的系统配置有问题吗?需要一些更加详细的说明和解决方法。
有19位网友表示赞同!
雪花ミ飞舞
sleep 这个命令真是太好用了!之前做一些自动化脚本的时候经常会遇到延迟的需求,现在终于解决了这个问题。感谢作者分享这样的宝贵知识!
有6位网友表示赞同!
珠穆郎马疯@
学习linux一直都是一个循序渐进的过程,这篇博客也让我进一步了解了这个系统中一些底层的机制,例如如何实现暂停执行的功能。不过我感觉文章内容还可以更加深入些,可以探讨一下sleep指令的各种参数和使用方法。
有14位网友表示赞同!
微信名字
有时候使用shell脚本需要控制程序的运行速度,sleep命令就派上用场了!这篇文章写的比较通俗易懂,非常适合像我这样的入门者学习。不过更希望作者能够介绍一些实际应用场景,这样就能更好地理解sleep指令的价值。
有20位网友表示赞同!
陌上花
感觉这篇文章有些过于简略了,缺少一些必要的背景知识和示例代码。对于初学者来说,这种解释方式可能不够清晰明了。建议在文章中添加更多具体的实例讲解,让读者更容易理解和掌握 sleep 命令的使用方法。
有20位网友表示赞同!
哭着哭着就萌了°
我最近在学习Linux系统编程,正好碰到了sleep的用法问题,这篇文章给了我很大的帮助!通过简洁的语言和清晰的步骤,让我快速了解了sleep命令的功能和使用方法。现在就可以轻松解决一些定时任务的需求了
有9位网友表示赞同!
敬情
linux 下实现 sleep 这种机制其实很常见,很多系统都支持类似的功能。不过这篇博客写的确实不错,能够把相对技术性的知识讲得通俗易懂,让初学者也能快速理解。 我也受益匪浅!
有9位网友表示赞同!
你的眸中有星辰
睡眠功能在脚本中非常实用呀!比如我要创建一个自动刷微博的脚本,就需要用到 sleep 命令来控制刷微博的速度,避免被封号。感谢作者为我们讲解这样一个重要的知识点!
有18位网友表示赞同!
猫腻
我曾经试着用其他工具代替 sleep, 结果效率都不行。最终还是发现 Linux下使用 sleep 方便快捷,省时省力!
有20位网友表示赞同!
抚涟i
看了这篇博客后终于明白为什么要学Linux了!原来还有这么多强大的功能隐藏起来呢!学习LINUX确实是一个非常值得的体验,可以让我更好地掌握更广泛的技术和知识。
有20位网友表示赞同!
七级床震
这篇文章太赞了!帮我解答了我一直以来在linux中关于 sleep命令的使用问题。建议博主能够多出一些高质量的文章分享给大家!
有13位网友表示赞同!
◆残留德花瓣
希望文章能提供更多具体的脚本案例,这样就能更直观地展示 sleep 命令的应用场景和效果,也能让人更快地上手实践
有9位网友表示赞同!
怀念·最初
睡函数的功能在编程中非常常见, 这篇文章讲解得很好, 帮助我理解 Linux 下如何实现这个功能。 我期待看到作者更多关于 Linux 的优质文章
有15位网友表示赞同!
鹿先森,教魔方
这篇博客虽然写的简单,但对初学者来说的确很有帮助。让我了解到Linux下可以用sleep实现定时功能,这在一些自动化脚本中非常有用。
有12位网友表示赞同!