linux下的定时器—多线程(2)

来源:互联网 发布:高安算法工程师人才网 编辑:程序博客网 时间:2024/05/03 00:52

      上次讲了关于linux下的定时器的一些函数,同时也讨论了一个问题:在多线程下怎样使用定时器。

      我在这里要达到的目的是:为一个或多个函数的运行设置定时器,比如:我希望A()函数在三秒后运行,B()函数在五秒后运行,而C( )函数则是每两秒运行一次,这时候该怎么办呢?

      我在这里增加了难度,定时一个函数比较好实现,但是当我们在多线程下(即便不是多线程)使用信号时,用alarm3)产生信号,signal(SIGALRM,A)运行函数时,我们会发现当有多个signal()函数存在时,信号不能确定让谁接收到,这个现象在多线程中会出现,即便你所运行的函数在不同的线程里。这是为什么呢?因为多线程公用的进程资源,信号也不例外,我们要解决的也就是这个问题了。

      linux函数中有类似的库函数,但是我们要模拟这个过程,通过自己解决这个问题。

      解决问题地方法:

1.     实现原理

运用链表实现函数的定时启动,我们设计这样一个结构体,让他作为链表的节点 struct time_func {

                      List_head  list//结构体节点的地址

                      Int        left_time ;//剩余时间

                      Void     *handle;//函数入口地址

                      Void     *date;//函数参数

}

List_head linux定义的关于链表操作的节点,他的地址就是该结构体的地址,这里不多说链表的操作,具体看linux的库函数。

Left_time 是函数离要运行还剩下的时间

其他两个是地址,其中参数date地址可以是结构体,这样可以是多个参数。

我们把要运行的函数地址和参数发到结构体中,(比如A()函数)left_time设置程3秒,插入到链表之中,然后每一秒遍历一次链表,

Left_time--,left_time减到0时,运行函数,这样就达到了函数定时运行的目的,多加几个节点就可以实现多函数定时运行。

2.     每一秒运行一次可以用alarm()函数,如果想扩展性好可以用select(),sitimer()函数实现,signal(SIGALRM, roll )函数接受一个信号后运行roll函数遍历链表,你可以在主线程中屏蔽了其他信号

3.     如果想每固定时间就重复运行一个函数的话,就在运行的函数中在添加一次时间节点。

改进与问题

我们可以把监控链表的过程单独设置一个线程,这样比较方便。

当然在此过程中一定要注意关于线程之间锁的问题,因为添加节点,遍历链表等过程需要添加线程锁,避免发生死锁问题,我就出现了这种问题,在和同学商量后,经过了改进,基本没有问题,为什么说基本?因为多线程是并发的,所以程序的问题有非再现行,检测时要多多运行几次,以免漏掉什么。

如果还有问题大家可以交流啊。

对了,不要忘了申请的内存要释放啊free

                                                                         O(_)O~

原创粉丝点击