linux sleep alarm,Linux环境编程之信号处理(三、利用alarm()和pause()函数实现sleep()函数)...

本文详细介绍了C语言中sleep()、alarm()和pause()函数的工作原理及用法,特别是如何通过alarm()和pause()实现sleep()的功能。通过示例代码展示了如何设置定时器并处理SIGALRM信号,以及如何处理进程挂起和信号中断的情况。
摘要由CSDN通过智能技术生成

sleep()是执行挂起一段时间,而alarm()函数是定时器,pause()函数则是挂起进程,当出现信号打断时,才会继续往前执行;

先来分享下alarm()函数,alarm()函数用来设置一个定时器,当时间超时时,会产生SIGALRM信号,该信号默认是终止该进程;

#include

unsigned int alarm(unsigned int seconds);

参数:unsigned int seconds表示经过seconds秒后会产生信号SIGALRM;

返回值:0或者以前设置的闹钟时间的余留秒数;

1、每个进程只能有一个闹钟时钟;

2、调用alarm()时,假如以前调用过alarm()函数,并且指定的时间还没到(即:还没超时,没有发送SIGALRM信号)。那么此次调用的alarm()函数会替代掉上一次的alarm()函数,并且返回值为上次调用alarm()函数中没有用完的时间;

3、本次调用alarm(0)函数会取消上一次未超时的定时器,返回剩余的时间;

下面也看看pause()函数:

#include

int pause(void);

pause()会把进程挂起来,直到一个信号处理程序执行完后,才会继续运行;

最后看看sleep()函数:

#include

unsigned int sleep(unsigned int seconds);

该函数使调用进程被挂起了,直到seconds后(超时后),或者捕捉到一个信号并且从信号处理函数返回后,该进程才能继续往下执行;返回值和alarm()函数的一样。

下面是利用alarm()函数和pause()函数来实现下sleep()函数:

#include

#include

#include

#include

static jmp_buf envAlarm;

static void myAlarm(int signo)// 自定义的SIGALRM定时器信号的处理函数

{

longjmp(envAlarm, 1);// 局部跳转

}

unsigned int mySleep(unsigned int sec)

{

unsigned int minSec, ret, tmp = 0;

if (signal(SIGALRM, myAlarm) == SIG_ERR)// 绑定SIGALRM和myAlarm()函数

return sec;

minSec = alarm(0);// 得到上一次未超时的定时器所剩的时间,防止冲刷掉上一次的真正的定时器(本函数的是实现sleep())

ret = sec > minSec ? (sec-minSec):0;// 得到返回值

if (setjmp(envAlarm) == 0){ // 局部跳转

if (minSec) // 这里考虑的是如果前面有设置定时器

alarm(minSec < sec ? minSec:sec);// 利用时间短的去做定时器

else // 如果前面没有设置定时器,则直接利用参数去挂起进程

alarm(sec);

sleep(9);// 这里是测试上一个alarm()函数到pause()之间延迟导致SIGALRM信号处理完后,pause()还没有触犯,则进程一直挂起

pause();

}

tmp = alarm(0);// 计算在睡眠时 有可能被其他信号打断,而剩下一些未睡眠的时间

if (minSec > sec){// 如果前面登记的定时器比睡眠时间长,则退出后还要把定时器复位为剩下时间的定时器

alarm(minSec-sec);// 定时器还剩多少时间,重新设置定时器

}

if (tmp)ret += tmp; // 统计所有剩余时间

return ret;

}

int main(int argc, char* argv[])

{

unsigned int otherSec;

alarm(6);

//sleep(4);

otherSec = mySleep(3);

printf("mySleep resturn:%u\n", otherSec);

return 0;

}

上面是通过局部跳转来实现sleep()函数的,当然还有使用信号屏蔽字来实现的,后面有时间会实现下。不知道上面的代码是否有漏洞,虽然这个代码量不多,但是要考虑的问题还是比较多的。如果有朋友发现了漏洞,欢迎指正!!谢谢!!

若有不正确之处,望大家指正,共同学习!谢谢!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值