alarm函数作用是设定一个计时器,到时间后会向进程发送信号。
它向进程发送SIGALRM信号。要注意的是,一个进程只能有一个闹钟时间,如果在调用alarm之前已设置过闹钟时间,则任何以前的闹钟时间都被新值所代替。
我们还可以调用alarm(0)来取消此闹钟,并返回剩余时间。
函数原型:
unsigned int alarm(unsigned int seconds);
函数参数:
seconds:指定的秒数
例子程序:test7.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>
typedef struct
{
long mtype;
char mbuf[1024];
}mymsg;
void SigAlarmProc()
{
printf("2222\n");
return;
}
int main(void)
{
int i, j;
int time = 5;
mymsg message;
sigset(SIGALRM, SigAlarmProc);//注册信号处理函数
alarm(time);//设置闹钟函数
printf("1111\n");
i = msgget(1004, 0666|IPC_CREAT);
j = msgrcv(i, (void *)&message, 1024, 0, 0);
if (j < 0)
{
printf("rev error, errno=%d\n", errno);
//exit(-1);
}
else
{
//显示取出的消息
printf("%s\n", message.mbuf);
}
printf("after msgcrv()\n");
alarm(0);
printf("3333\n");
return 0;
}
执行结果:
[root@server ~]# ./test7
1111
2222
rev error, errno=4
after msgcrv()
3333
程序执行过程:
先在sigset注册信号处理函数,然后设置闹钟函数,然后打印1111。
在msgrcv()处阻塞,5秒后alarm时间到了,跳转到SigAlarmProc,打印2222。
然后发现消息队列被信号处理中断了,没有继续处于接收的阻塞状态,打印了errno=4。网上说“msgsnd/msgrcv将返回-1,errno被设置为EINTR(-4)”。
随后继续执行,打印后两句提示。
一般来说信号处理是一种中断机制,执行完信号处理函数后,程序会回到中断的地方继续执行下去。
网上找了一下:
对于linux的信号,如果用户自己注册了某信号的处理函数,那么他的执行过程是这样的。
1.收到该信号后马上进入内核态
2.内核将进入内核前的用户现场(寄存器、标志位等)保存,具体是建立一个数据结构(《linux内核源码》一书中称为“原始框架”)
3.调用该信号的处理函数
4.将用户现场恢复,继续执行
例子程序:test8.c
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
void SigAlarmProc()
{
printf("2222\n");
return;
}
int main(void)
{
int i;
int time = 5;
sigset(SIGALRM, SigAlarmProc);//注册信号处理函数
alarm(time);//设置闹钟函数
printf("1111\n");
for (i = 0; i < 10; i++)
{
printf("i=%d\n", i);
sleep(1);
}
alarm(0);
printf("3333\n");
return 0;
}
执行结果:
[root@server ~]# ./test8
1111
i=0
i=1
i=2
i=3
i=4
2222
i=5
i=6
i=7
i=8
i=9
3333
说明:
先注册信号处理函数,设置闹钟函数,打印1111。
在for循环中,打印一个i的值,然后睡眠1秒钟。
我们可以看到在i=4时,闹钟函数发出了信号,然后执行了SigAlarmProc,打印2222。
SigAlarmProc执行完后又继续回到for循环打印i的值,然后退出。
所以一般情况下,进程收到信号,执行完信号处理函数会回到中断的地方继续执行程序。
忽略信号
如果想忽略某个信号,使用:
sigset(SIGALRM, SIG_IGN);
参考资料:
http://blog.csdn.net/dongzhongshu/article/details/6270261
http://blog.chinaunix.net/uid-20558821-id-2801753.html
http://blog.csdn.net/mwx1234/article/details/7189791