3.5.4.alarm和pause函数
3.5.4.1、alarm函数: 内核提供的 闹钟,时间到了,会帮我们执行一个函数
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
介绍:
alarm()函数 安排将 SIGALRM 信号传递给调用 以秒为单位处理。
unsigned int seconds 如果秒数为零,则取消任何挂起的闹钟。
在任何情况下,之前设置的任何警报()都会被取消。
(1)内核以API形式提供的闹钟
(2)编程实践
#include "stdio.h"
#include <signal.h>
#include <unistd.h>
void func(int sig)
{
if(sig == SIGALRM )
{
printf("alarm happened \n"); /* 闹钟触发 */
}
}
int main(void)
{
unsigned int ret = -1;
signal(SIGALRM, func); /*主动捕获信号SIGALRM 信号 1.当收到SIGALRM 信号后, 回去执行 func 这个函数*/
ret = alarm(3); /* alarm 定义 3 秒钟后, 会收到 SIGALRM 一个信号 */
printf("ret = %d \n", ret); /* 第一次 调用 alarm 返回值 返回一个 0 */
while(1);
return 0;
}
运行结果:
2. 多次 执行 alarm() , 最后的 alarm 会覆盖 前面的 alarm
#include "stdio.h"
#include <signal.h>
#include <unistd.h>
void func(int sig)
{
if(sig == SIGALRM )
{
printf("alarm happened \n"); /* 闹钟触发 */
}
}
int main(void)
{
unsigned int ret = -1;
struct sigaction act = {0}; /* 先定义 sigaction 第二参数 act,全部 赋值为 0 */
act.sa_handler = func; /* act.sa_handler赋值,绑定 func */
//signal(SIGALRM, func); /*主动捕获信号SIGALRM 信号 1.当收到SIGALRM 信号后, 回去执行 func 这个函数*/
sigaction(SIGALRM, &act, NULL);/*主动捕获信号SIGALRM 信号 1.当收到SIGALRM 信号后, 回去执行 func 这个函数, 第3参数 NULL*/
ret = alarm(5); /* alarm 定义 5 秒钟后, 会收到 SIGALRM 一个信号,不会执行 func */
printf("1st, ret = %d \n", ret); /* 第一次 调用 alarm 返回值 返回一个 0 */
sleep(3);
ret = alarm(5); /* alarm 定义 5 秒钟后, 会收到 SIGALRM 一个信号 ,不会执行 func */
printf("2st, ret = %d \n", ret); /* 第2次 调用 alarm 返回值 返回 : 第一次调用alarm 后, sleep(3)延时3秒, 会把 alarm(5-3),这里的3是sleep(3),所以 第二次调用 alarm 后返回值 为2 */
sleep(1);
ret = alarm(5); /* alarm 定义 5 秒钟后, 会收到 SIGALRM 一个信号, 5 秒后执行 func */
printf("3st, ret = %d \n", ret); /* 第3次 调用 alarm 返回值:第二次调用alarm 后, sleep(1)延时1秒, 会把 alarm(5-1),这里的1是sleep(1),所以 第3次调用 alarm 后返回值 为4 */
while(1);
return 0;
}
运行结果:
3.5.4.2、pause函数
while(1); cpu 被当前进程一直占用,
pause(); 让当前 cpu 挂起, 并交出 cpu 的运行权限
#include "stdio.h"
#include <signal.h>
#include <unistd.h>
void func(int sig)
{
if(sig == SIGALRM )
{
printf("alarm happened \n"); /* 闹钟触发 */
}
}
int main(void)
{
unsigned int ret = -1;
struct sigaction act = {0}; /* 先定义 sigaction 第二参数 act,全部 赋值为 0 */
act.sa_handler = func; /* act.sa_handler赋值,绑定 func */
//signal(SIGALRM, func); /*主动捕获信号SIGALRM 信号 1.当收到SIGALRM 信号后, 回去执行 func 这个函数*/
sigaction(SIGALRM, &act, NULL);
ret = alarm(5); /* alarm 定义 5 秒钟后, 会收到 SIGALRM 一个信号,执行 func */
printf("1st, ret = %d \n", ret); /* 第一次 调用 alarm 返回值 返回一个 0 */
/**********************************
* pause函数的作用就是让当前进程暂停运行,交出CPU给其他进程去执行。
* 当当前进程进入pause状态后当前进程会表现为“卡住、阻塞住”,
* 要退出pause状态当前进程需要被信号唤醒。
*********************************/
pause();
return 0;
}
运行结果
(1)内核挂起
(2)代码实践
pause函数的作用就是让当前进程暂停运行,交出CPU给其他进程去执行。当当前进程进入pause状态后当前进程会表现为“卡住、阻塞住”,要退出pause状态当前进程需要被信号唤醒。
3.5.4.3、使用alarm和pause来模拟sleep
#include "stdio.h"
#include <signal.h>
#include <unistd.h>
void mysleep(unsigned int seconds);
void func(int sig)
{
}
int main(void)
{
printf("使用alarm和pause来模拟sleep 开始 \n ");
mysleep(5);
printf("使用alarm和pause来模拟sleep 结束 \n ");
return 0;
}
void mysleep(unsigned int seconds)
{
struct sigaction act = {0}; /* 先定义 sigaction 第二参数 act,全部 赋值为 0 */
act.sa_handler = func; /* act.sa_handler赋值,绑定 func , func 是一个空函数*/
sigaction(SIGALRM, &act, NULL);/*主动捕获信号SIGALRM 信号 1.当收到SIGALRM 信号后, 回去执行 func 这个函数, 第3参数 NULL */
alarm(seconds);
/**********************************
* pause函数的作用就是让当前进程暂停运行,交出CPU给其他进程去执行。
* 当当前进程进入pause状态后当前进程会表现为“卡住、阻塞住”,
* 要退出pause状态当前进程需要被信号唤醒。
*********************************/
pause();
}
运行结果