mysleep
来源:互联网 发布:软件开发安卓 编辑:程序博客网 时间:2024/06/05 01:08
mysleep
普通版本的mysleep:
1、 main函数调用mysleep函数,后者调用sigaction注册了SIGALRM信号的处理函数handler。
2、调用alarm(time)设定闹钟。
3、调用pause等待,内核切换到别的进程运行。
4、time秒之后,闹钟超时,内核发SIGALRM给这个进程。
5、从内核态返回这个进程的用户态之前处理未决信号,发现有SIGALRM信号,其处理函数是handler。
6、切换到用户态执行handler函数,进入handler函数时SIGALRM信号被自动屏蔽, 从handler函数返回时SIGALRM信号自动解除屏蔽。然后自动执行系统调用sigreturn再次进入 内核,再返回用户态继续执行进程的主控制流程(main函数调用的mysleep函数)。
6、切换到用户态执行handler函数,进入handler函数时SIGALRM信号被自动屏蔽, 从handler函数返回时SIGALRM信号自动解除屏蔽。然后自动执行系统调用sigreturn再次进入 内核,再返回用户态继续执行进程的主控制流程(main函数调用的mysleep函数)。
7、pause函数返回-1,然后调用alarm(0)取消闹钟,调用sigaction恢复SIGALRM信号以前的处理 动作。
(1)普通版本mysleep代码如下:
#include<stdio.h> #include<signal.h> #include<unistd.h> void handler(int signum) {} int mysleep(int time) { struct sigaction act,oact; act.sa_handler=handler; act.sa_flags=0; sigset_t sa_mask; sigemptyset(&sa_mask); sigaction(SIGALRM,&act,&oact); alarm(time); pause(); int ret=alarm(0); sigaction(SIGALRM,&act,NULL); return ret; } int main() { while(1) { mysleep(3); printf("I am sleep,I will sleeping 3 second\n"); } return 0; }
(2)规避竞态mysleep
#include<stdio.h> #include<signal.h> #include<unistd.h> #include<stdlib.h> #include<sys/types.h> int sigsuspend(const sigset_t *sigmask); void handler(int signum) {} int mysleep(int time) { struct sigaction act,oact; sigset_t newmask,oldmask,suspmask; act.sa_handler=handler; act.sa_flags=0; sigset_t sa_mask; sigemptyset(&sa_mask); sigaction(SIGALRM,&act,&oact); sigemptyset(&newmask); sigaddset(&newmask,SIGALRM); sigprocmask(SIG_BLOCK,&newmask,&oldmask);//屏蔽信号SIGALRM alarm(time); suspmask=oldmask; sigdelset(&suspmask,SIGALRM); sigsuspend(&suspmask); int ret=alarm(0); sigaction(SIGALRM,&act,NULL); sigprocmask(SIG_SETMASK,&oldmask,NULL); return ret; } int main() { while(1) { mysleep(3); printf("I am sleep,I will sleeping 3 second\n"); } return 0; }
虽然两个mysleep运行的结果目前表面上都是一样的,但系统运⾏的时序(Timing)并不像我们写程序时所设想的那样。在普通版本中,虽然alarm(time)紧接着的下⼀行就是pause(),但是无法保证pause()一定会在调用alarm(time)之后的time秒之内被调用。 被切换后,若触发SIGALRM信号,信号会立即递达,当该进程切回来的时候,接收不到SIGALRM信号,不会再次接收到该信号,线程一直处于挂起状态,得不到激活。在规避竞态版本下,对SIGALRM信号进行了屏蔽,被切出去之后,该信号也不会被递达。因为是原语操作,取消屏蔽字后 ,程序正常激活。
阅读全文
2 0
- mysleep
- mysleep
- 编写mysleep
- 编写mysleep
- 编写mysleep
- mysleep与竞态条件下的mysleep
- Linux中的mysleep函数
- linux mysleep实现
- Linux 信号之mysleep
- 实现sleep-mysleep
- mysleep与sigsuspend函数
- 编写一个mysleep函数
- Linux下的mysleep
- 实现睡眠函数mysleep
- mysleep的实现
- 普通版本mysleep和规避竞态条件的mysleep
- 实验五:实现mysleep函数
- Linux C 实现mysleep数
- 关于AS3语言Flash的Stage3D在不同的AGAL版本中寄存器的数量限制
- EMV规范(五)——脱机数据认证
- Android Studio SVN 使用方法
- sql语法请教,这一行某列的数是上一行该列,经过计算后得出来的数,语法怎么写
- 常用激活函数(Activation Function)
- mysleep
- POJ 1017 Packets 贪心
- springMVC 接收参数415
- linux下安装jdk1.8
- 常用的日期格式化转换符
- pip安装的时候报错
- Linux android下常用命令
- HDU
- 类加载器子系统