linux系统编程之信号(七)
今天继续学习信号,主要是学习关于时间和定时器相关的函数的使用,关于这个实际上有很多内容,这里先简要进行说明,等之后再慢慢进行相关深入,也主要是为接下来要做的一个综合linux系统编程的例子做准备,好了,进入正题:
三种不同精度的睡眠:
关于这个函数,实际上已经在之前使用过了,具体可以参考博文:http://www.cnblogs.com/webor2006/p/3525517.html
查看man帮助:
以微秒为单位,那微秒跟秒是什么关系呢?
1秒=10的3次方毫秒=10的6次方微妙
以纳秒为单位的休眠
三种时间结构:
setitimer:
查看一下man帮助,其中ittimerval结构体的内容如下:
对于上面的描述可能比较抽象,下面以实际例子来进行说明:
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> #include <sys/time.h>//另外需要包含头文件 #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) void handler(int sig) { printf("recv a sig=%d\n", sig); } int main(int argc, char *argv[]) { if (signal(SIGALRM, handler) == SIG_ERR)//注册一个SIGALRM信号 ERR_EXIT("signal error"); struct timeval tv_interval = {1, 0}; struct timeval tv_value = {5, 0};//那这两个值有什么意义呢? struct itimerval it; it.it_interval = tv_interval; it.it_value = tv_value; setitimer(ITIMER_REAL, &it, NULL);//这个函数会间接性地产生SIGALRM信号,需传递ITIMER_REAL参数 for (;;) pause(); return 0; }
编译运行:
从运行结果可以知道,等待五秒钟之后才打印出来,以后每过一秒打印,那再回过头来理解下代码:
struct timeval tv_interval = {1, 0};//之后产生信号的间隔时间
struct timeval tv_value = {5, 0};//第一次产生信号的时间
另外,setitimer的第三个参数ovalue是干嘛用的呢?下面用实验也来说明下:
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> #include <sys/time.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) int main(int argc, char *argv[]) { struct timeval tv_interval = {1, 0}; struct timeval tv_value = {1, 0};//第一次产生信号需要等待1秒 struct itimerval it; it.it_interval = tv_interval; it.it_value = tv_value; setitimer(ITIMER_REAL, &it, NULL); int i; for (i=0; i<10000; i++);//故意产生10000次的循环,运行时间肯定不足一秒,所以目的也就是为了看到第三个参数的效果 ; struct itimerval oit; setitimer(ITIMER_REAL, &it, &oit);//在第一次信号还没有产生之时,又重新设置一个定时,这时oit会存放上一次设置的时钟它还剩余的时间 printf("%d %d %d %d\n", (int)oit.it_interval.tv_sec, (int)oit.it_interval.tv_usec, (int)oit.it_value.tv_sec, (int)oit.it_value.tv_usec); return 0; }
编译运行:
【注意】:这个效果跟下面要说明的getitimer效果一样,但是有一些区别,getitimer得到剩余时间是不重新设置时钟。
另外还有一个相关函数:
代码如下:
#include <unistd.h> #include <sys/stat.h> #include <sys/wait.h> #include <sys/types.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <signal.h> #include <sys/time.h> #define ERR_EXIT(m) \ do \ { \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) int main(int argc, char *argv[]) { struct timeval tv_interval = {1, 0}; struct timeval tv_value = {1, 0}; struct itimerval it; it.it_interval = tv_interval; it.it_value = tv_value; setitimer(ITIMER_REAL, &it, NULL); int i; for (i=0; i<10000; i++); ; getitimer(ITIMER_REAL, &it);//获得产生首次信号的时间,并没有从 printf("%d %d %d %d\n", (int)it.it_interval.tv_sec, (int)it.it_interval.tv_usec, (int)it.it_value.tv_sec, (int)it.it_value.tv_usec); return 0; }
运行效果一样,这里就不演示了,好了,关于信号的学习就告一段落了,下个章节再见!!