Linux 下的定时器(1)

        今天博客开张了,现在准备工作了——实习阶段,发现中国的那句俗话“啥玩意不会”,但是越是这样越发现每天学会的东西很多,今天把前两天要写的关于linux下的定时器的一些东西写一下。

      linux下的器定时作用的函数很多,比如常用的sleep()函数,这里不再过多说这个。主要说的关于定时器精度和循环定时器的应用,尤其是在多线程应用过程中所要注意的定时器问题。

 

1. alarm()和signal()函数

      alarm()函数在自己规定的时间到来时,向系统发送一个名为SIGALRM的信号,如果你想在自己规定的时间后运行一个函数,那么就是用signal(int ,void*)函数,他的第一个参数是接收到的信号,比如说是SIGALRM,第二个参数是要运行的函数的地址,这样就达到了在某个时间后运行一个函数的目的。但是在多线程的程序里会出现差错,可以试一试如果发送一个信号后,有多个线程signal会出现什么差错。

 

2. setitimer()精确定时

    此函数可以达到微妙级别的定时(但要考路到内核HZ,不一定能达到),我们可以看一下他的参数

setitmer(int which, const struct itimerval *value, struct itimerval *ovalue)

 

第一个参数是信号类型具体可以查到,而itimerval结构体,就是定义触发时间的结构体,它包含两个参数 :一个是下次定时的时间取值(分为秒和微妙)一个是本次定时的设置,具体结构可以man 到。最后一个参数可以设置为NULL,此函数虽然达到了精确定时,但是在多线程里好像只能三个吧,(多指教),并且会产生与上面说的同一类问题如果你用signal接受的话。

 

3. select()函数

 

     此函数使用在文件操作里面的,当然socket编程不会少了它,我在使用计时器时看到了网上使用它的一些例子,但是立即就放弃了,因为感觉很难似的,在操作文件编程时也没着重研究,过了几天学习socket并发编程时,又一次见到了她,这是才发现基本上是很简单的,尤其是用在计时器上,(教训啊)这里简单介绍一下相关计时器的编程,socket以后再说。

      好了,开始了:

int select(int n, fd_set *readfds, fe_set *writefds, fd_set *exceptfds, struct timeval *timeout );

 

看上去很难吧,O(∩_∩)O~,现在就看计时器了所以就把中间三个参数设成NULL,不用管,第一个参数设置成 0,最后一个就够体和上面的差不多:

struct timeval{

  long tv_sec; // seconds

  long tv_usec; // microseconds

  }

可以精确到微妙,可以了吧,设置上时间,比如 struct timeval time = { 1,30 },此时设置的是一秒30微妙,此时变成了:

select( 0, NULL, NULL,NULL,time),简单了吧,一个一秒30微妙的定时器了,每到时间了就触发了,好像没信号,也没什么特殊要求(比如不能超过三个),按道理来说是应该每隔一定时间就触发一次,但是在伯克利系统中(什么是伯克利啊?——自己查吧)他不是自动触发的要设置信号(用sigaction() 函数)这个不用管,好了,如果你就想定时一次,有一个就行了,但是你想每隔time一次 呢,好办 while(1){....select(....).....}无限循环不就可以了。

综合分析::

       sleep() alarm() 是精确到秒的,setitimer(),select()是精确到微妙的,还有一个是精确到纳秒的,但是由于系统内核的原因好像不是这么精确,微妙就不错了。

       setitmer()可以循环计时,其他不行,如果不是在多线程里没什么问题。

那么在多线程里会出什么问题呢:在多线程里信号时共享的,当然进程资源也是共享的,所以一个alarm(),setitimer()发信号都能收到,如果好几个线程都接手signal()那么就不能确定哪一个线程收到了信号,所以有随机性,那么怎样在多线程环境里设置定时器呢?这里说的是设置一个定时器,到时间了运行设定好的函数,这个问题下一篇来讲,当然系统有相应函数库,我说的是自己编出来了。

                                                                                                                      ——冰洋 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值