需要处理大量计时器/超时的建议

时间:2015-11-03 16:09:00

标签: c multithreading timer

我正在重新设计现有的L2TP(第2层隧道协议)代码。 对于L2TP,我们支持的隧道数量为96K。 L2TP协议具有保持活动机制,需要发送HELLO msges。

假设我们有96,000个隧道,L2TPd需要在配置的超时值后发送HELLO消息,实现它的最佳方法是什么?

现在,我们有一个计时器线程,每1秒,我们迭代并发送HELLO msges。这种设计是一种旧的设计,现在没有扩展。

请建议我设计一个处理大量计时器的设计。

3 个答案:

答案 0 :(得分:0)

有几种方法可以实现计时器:

1)选择:此系统调用允许您等待文件描述符,然后唤醒。您可以等待一个不作为超时的文件描述符

2)Posix条件变量:与select类似,它们内置了超时机制。

3)如果您使用的是UNIX,则可以将UNIX信号设置为唤醒。

这些都是基本的想法。您可以看到它们与多个计时器的匹配程度如何;我猜你必须有一些condvars /选择一些线程。

根据您想要的行为,您可能需要每100个定时器左右一个线程,并使用上述机制之一唤醒 其中一个计时器。你有一个线程坐在一个循环中,并保持 跟踪100次超时中的每一次,然后醒来。

一旦超过100个计时器,您只需创建一个新线程并让它管理接下来的100个计时器,依此类推。

我不知道100是否是正确的粒度,但它是你玩的东西。

希望这就是你要找的东西。

答案 1 :(得分:0)

通常,这种要求通过增量队列来满足。当需要超时时,获取系统滴答计数并为其添加超时间隔。这给出了Timeout Expiry Tick Count,(TETC)。将套接字对象插入到一个队列中,该队列通过减少TETC进行排序,并让线程等待队列头部项目的TETC。

通常,对于asocket超时,队列插入很便宜,因为有许多超时具有相同的间隔,因此通常会在队列尾部发生新的超时插入。

队列的管理,(实际上,因为插入排序队列可以在任何地方进行,它更像是列表而不是队列,但无论如何:),最好保留一个通常执行定时等待的超时线程在最低TETC的condvar或信号量上。然后,新的超时对象可以在线程安全的并发队列中排队到线程,并通过sema / condvar发送到超时处理程序线程。

当超时线程在TETC超时时就绪,它可以调用对象本身的一些'OnTimeout'方法,或者它可能将超时对象放到线程池输入队列中。

这种增量队列比任何轮询方案更有效地处理大量超时,特别是对于间隔时间较长的要求。不需要轮询,连续迭代不会浪费CPU /内存带宽,典型的延迟将是一个系统时钟或两个。

答案 2 :(得分:0)

它取决于处理器/操作系统,内核版本,架构。

在linux中,其中一个选项是将其计时器功能用于多个计时器。可以使用linux中的add_timer来添加计时器。您可以使用timer_list定义它,并使用init_timer初始化timer的内部值。 接下来,在为各个定时器填充timer_list(超时(expire),超时(函数)后执行的函数,函数(数据)的参数)后,使用add_timer注册它。如果jiffies大于或等于timeout(expire),则应触发相应的计时器处理程序(函数)。

某些处理器配置了定时器轮(由多个队列组成,这些队列在时隙中均匀放置),可根据需要配置各种定时器,超时。