C和c++ 定时器管理队列结构

April 11, 2012 | 0 Minute Read

下载LOFTER我的照片书 | 不知道asio::deadline_timer 用的比较多的时候,性能怎么样? 打算自己在上层实现一个定时器的管理。这个为了能够在很多定时器里面找到最近超时的定时器,又要用比较小的代价。很多事件驱动库都是用个最小堆结构来管理的吧,好像linux内核里面分了几个长短不一的链表,这样每次只要去最快超时的那个队列去查找就可以了。不过最好就是只用一个定时器啦,这样就比较很多定时器查找的消耗,想以前 Linux的scsi驱动层,以前为每个request设一个定时器,后来改成一个队列一个定时器了。

   不过自己管理的,如果有很多个不同的超时时间,还是要用堆啊,看了一下c++  stl里面的priority_queue这个容器明显是一个堆来的,确实可以这样用的,但他不支持从任意位置删除元素,只能从堆的顶端去删一个。他其实不是不能随机访问的,删掉任意一个位置元素的话,也是需要重新调整堆结构的。但这样用来管理定时器就不是很方便了,定时器实现需要能够频繁的取消或者说删除定时器操作吧,stl  里面的make_heap push_heap pop_heap这些算法也差不多,都是不能任意位置去删的。

    看到网上有人还是硬是用priority_queue 加 vector 和 stack那些去做, 他其实说priority_queue  不能删吧,他就东西保存在vector里面,再priority_queue 里面保存一个指向vector  里面一个元素的索引,删的时候不是去priority_queue  里面删除元素,而是设置相关的vector里面的标志。  然后从priority_queue 里面取最近的定时器出来的时候,可以根据vector里面的值判断是不是这个定时器已经被删了然后跳过就可以了。 stack用来保存 vector里面的空闲的位置。

 

 

看了一下      libev  和  asio里面的  timer_queue 的代码,其实他们也是用“堆”啊,但不过都自己的写的代码。感兴趣的可以去看一下,asio的代码在这两个头文件里面

detail/timer_queue.hpp

detail/impl/win_iocp_io_service.hpp。

 考虑到自己弄的复杂度,直接上多个asio::deadline_timer算了,自己就不在管理超时时间队列了。希望asio的这个实现的timer是可以大量使用的,不要表现的太差!