我正在重新设计一个现有的L2TP(第2层隧道协议)代码。对于L2TP,我们支持的通道数是96K。L2TP协议具有保活机制,需要在该机制中发送HELLO消息。
假设我们有96,000个隧道,L2TPd需要在配置的超时值后为其发送HELLO msg,那么实现它的最佳方式是什么?
现在,我们有了一个计时器线程,每隔1秒,我们就会迭代并发送HELLO消息。这个设计是一个旧的设计,现在还不能扩展。
请建议我一个设计,以处理大量的计时器。
发布于 2015-11-04 00:24:58
有几种方法可以实现计时器:
1) select:此系统调用允许您等待文件描述符,然后唤醒。您可以等待不执行任何操作的文件描述符作为超时
2) Posix条件变量:与select类似,它们具有内置的超时机制。
3)如果您使用的是UNIX,您可以设置UNIX信号来唤醒。
这些都是基本的想法。您可以看到它们如何很好地扩展到多个计时器;我猜您必须为一些线程使用多个condvar/select。
根据你想要的行为,你可能需要为每100个计时器创建一个线程,并使用上面的机制之一来唤醒其中一个计时器。你会有一个循环中的线程,跟踪100个超时的每一个,然后唤醒。
一旦超过100个计时器,您只需创建一个新线程,并让它管理接下来的100个计时器,依此类推。
我不知道100是不是合适的粒度,但它是你可以尝试的东西。
希望这就是你要找的。
发布于 2015-11-04 01:38:02
通常,增量队列可以满足这样的要求。当需要超时时,获取系统节拍计数并添加超时间隔。这给出了超时过期滴答计数(TETC)。将socket对象插入到按TETC递减排序的队列中,并让线程等待位于队列头部的项的TETC。
通常,对于套接字超时,插入队列的成本很低,因为有许多具有相同间隔的超时,因此新的超时插入通常会在队列尾部发生。
队列的管理(实际上,因为插入到排序队列的操作可以发生在任何地方,它更像是一个列表而不是一个队列,但是不管怎样:),最好由一个超时线程来管理,该线程通常在condvar或semaphore上执行对最低TETC的定时等待。新的超时-对象可以在线程安全的并发队列中排队到线程,并通过sema/condvar通知超时处理程序线程。
当超时线程在TETC超时准备就绪时,它可以调用对象本身的某个'OnTimeout‘方法,或者它可以将超时对象放到线程池输入队列中。
与任何轮询方案相比,这种增量队列在处理大量超时时要高效得多,特别是对于具有较长间隔的需求。不需要轮询,不会在连续迭代中浪费CPU/内存带宽,典型的延迟将是一两个系统时钟节拍。
发布于 2015-11-04 02:57:48
它取决于处理器/操作系统、内核版本和体系结构。
在linux中,一种选择是将其计时器功能用于多个计时器。在linux中,可以使用add_timer添加计时器。您可以使用timer_list定义它,并使用init_timer初始化计时器的内部值。然后,在为相应的定时器适当填充timer_list(超时(Expire),超时后要执行的函数( function ),函数的参数(Data))之后,使用add_timer对其进行注册。如果jiffies大于或等于timeout(expire),则应触发相应的计时器处理程序(函数)。
一些处理器提供了定时器轮子(由多个在时间上相等地放置在插槽中的队列组成),可以根据需要为各种定时器、超时进行配置。
https://stackoverflow.com/questions/33503801
复制相似问题