LINUX下实现睡眠

sleep:普通版本1、基本设计思路:1>注册SIGALRM信号的处理函数;2>调用alarm(nsecs)设定闹钟;3>调⽤pause等待,

各位老铁们好,相信很多人对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;

}

相关函数分析:

LINUX下实现睡眠

[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;

LINUX下实现睡眠

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信号已经被处理了,这个过程会导致错误。

在进程运行过程中,由于异步特性,可能会因为时序问题而导致其他优先级较高的进程出现错误。此类问题称为竞争条件。

用户评论

LINUX下实现睡眠
纯情小火鸡

突然发现自己用的linux指令真的太少了!这篇博客终于教会我了如何使用sleep命令了,之前总是不知道该用什么代替Windows那个睡醒的功能。现在可以写一些定时任务了

    有18位网友表示赞同!

LINUX下实现睡眠
生命一旅程

这篇文章写得太简单了吧,像是在讲给小朋友听的感觉… 我希望能看到一些更复杂的用法,比如在循环中使用sleep,或者结合其他工具实现更高级的定时功能。

    有17位网友表示赞同!

LINUX下实现睡眠
心已麻木i

终于明白为什么有些人总是说linux才是真正的自由操作系统!自带这么强大的实用工具,还能玩出这么多花样!感谢作者分享这篇文章!

    有12位网友表示赞同!

LINUX下实现睡眠
三年约

我一直都用的是Python里的time模块来实现睡眠效果,没想到Linux下还有专门的sleep命令可以用。感觉这个commands really makes things simpler

    有6位网友表示赞同!

LINUX下实现睡眠
凉凉凉”凉但是人心

我这里好像有点问题啊,一直运行sleep指令就停在那不动了… 可能是我的系统配置有问题吗?需要一些更加详细的说明和解决方法。

    有19位网友表示赞同!

LINUX下实现睡眠
雪花ミ飞舞

sleep 这个命令真是太好用了!之前做一些自动化脚本的时候经常会遇到延迟的需求,现在终于解决了这个问题。感谢作者分享这样的宝贵知识!

    有6位网友表示赞同!

LINUX下实现睡眠
珠穆郎马疯@

学习linux一直都是一个循序渐进的过程,这篇博客也让我进一步了解了这个系统中一些底层的机制,例如如何实现暂停执行的功能。不过我感觉文章内容还可以更加深入些,可以探讨一下sleep指令的各种参数和使用方法。

    有14位网友表示赞同!

LINUX下实现睡眠
微信名字

有时候使用shell脚本需要控制程序的运行速度,sleep命令就派上用场了!这篇文章写的比较通俗易懂,非常适合像我这样的入门者学习。不过更希望作者能够介绍一些实际应用场景,这样就能更好地理解sleep指令的价值。

    有20位网友表示赞同!

LINUX下实现睡眠
陌上花

感觉这篇文章有些过于简略了,缺少一些必要的背景知识和示例代码。对于初学者来说,这种解释方式可能不够清晰明了。建议在文章中添加更多具体的实例讲解,让读者更容易理解和掌握 sleep 命令的使用方法。

    有20位网友表示赞同!

LINUX下实现睡眠
哭着哭着就萌了°

我最近在学习Linux系统编程,正好碰到了sleep的用法问题,这篇文章给了我很大的帮助!通过简洁的语言和清晰的步骤,让我快速了解了sleep命令的功能和使用方法。现在就可以轻松解决一些定时任务的需求了

    有9位网友表示赞同!

LINUX下实现睡眠
敬情

linux 下实现 sleep 这种机制其实很常见,很多系统都支持类似的功能。不过这篇博客写的确实不错,能够把相对技术性的知识讲得通俗易懂,让初学者也能快速理解。 我也受益匪浅!

    有9位网友表示赞同!

LINUX下实现睡眠
你的眸中有星辰

睡眠功能在脚本中非常实用呀!比如我要创建一个自动刷微博的脚本,就需要用到 sleep 命令来控制刷微博的速度,避免被封号。感谢作者为我们讲解这样一个重要的知识点!

    有18位网友表示赞同!

LINUX下实现睡眠
猫腻

我曾经试着用其他工具代替 sleep, 结果效率都不行。最终还是发现 Linux下使用 sleep 方便快捷,省时省力!

    有20位网友表示赞同!

LINUX下实现睡眠
抚涟i

看了这篇博客后终于明白为什么要学Linux了!原来还有这么多强大的功能隐藏起来呢!学习LINUX确实是一个非常值得的体验,可以让我更好地掌握更广泛的技术和知识。

    有20位网友表示赞同!

LINUX下实现睡眠
七级床震

这篇文章太赞了!帮我解答了我一直以来在linux中关于 sleep命令的使用问题。建议博主能够多出一些高质量的文章分享给大家!

    有13位网友表示赞同!

LINUX下实现睡眠
◆残留德花瓣

希望文章能提供更多具体的脚本案例,这样就能更直观地展示 sleep 命令的应用场景和效果,也能让人更快地上手实践

    有9位网友表示赞同!

LINUX下实现睡眠
怀念·最初

睡函数的功能在编程中非常常见, 这篇文章讲解得很好, 帮助我理解 Linux 下如何实现这个功能。 我期待看到作者更多关于 Linux 的优质文章

    有15位网友表示赞同!

LINUX下实现睡眠
鹿先森,教魔方

这篇博客虽然写的简单,但对初学者来说的确很有帮助。让我了解到Linux下可以用sleep实现定时功能,这在一些自动化脚本中非常有用。

    有12位网友表示赞同!

原创文章,作者:小su,如若转载,请注明出处:https://www.sudun.com/ask/113452.html

(0)
小su's avatar小su
上一篇 2024年9月1日 上午12:31
下一篇 2024年9月1日 上午12:34

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注