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