函数原型:
- int pause(void);
函数作用:
进程调用pause函数时,会造成进程主动挂起(处于阻塞状态,并主动放弃CPU),并且等待信号将其唤醒。
返回值:
我们知道,信号的处理方式有三种:1. 默认动作;2. 忽略处理;3. 捕捉。进程收到一个信号后,会先处理响应信号,再唤醒pause函数。于是有下面几种情况:
- 如果信号的默认处理动作是终止进程,则进程将被终止,也就是说一收到信号进程就终止了,pause函数根本就没有机会返回;
- 如果信号的默认处理动作是忽略,则进程将直接忽略该信号,相当于没收到这个信号,进程继续处于挂起状态,pause函数不返回;
- 如果信号的处理动作是捕捉,则进程调用完信号处理函数之后,pause返回-1,errno设置为EINTR,表示“被信号中断”。
- pause收到的信号不能被屏蔽,如果被屏蔽,那么pause就不能被唤醒。
因为alarm函数可以在设定的时间之后发送SIGALRM信号,pause函数又可以将进程挂起等待信号,则二者结合可以自己写一个sleep函数,如下:
- #include <unistd.h>
- #include <signal.h>
- #include <stdio.h>
- void sig_alrm(int signo)
- {
- /* nothing to do */
- }
- unsigned int mysleep(unsigned int nsecs)
- {
- unsigned int unslept;
- signal(SIGALRM, &sig_alrm);
- unslept = alarm(nsecs);
- pause();
- return unslept;
- }
- int main(void)
- {
- while(1){
- mysleep(2);
- printf("Two seconds passed\n");
- }
- return 0;
- }
##时序竞态前导例
在讲时序竞态具体现象之前,我们先来看一个生活中常见的场景:
想午睡10分钟,于是定了个10分钟的闹钟,希望10分钟后闹钟将自己叫醒。
正常情况:定好闹钟,午睡,10分钟后闹钟叫醒自己;
异常情况:定好闹钟,躺下睡觉2分钟,被同学叫醒去打球,打了20分钟后回来继续睡觉。但在打球期间,闹钟早就响过了,将不会再唤醒自己。
这个例子与之后要讲的时序竞态有很大的相似之处。