SIGALRM超时 - 它如何影响现有运营?

时间:2010-07-13 21:20:06

标签: c++ select performance timeout signals

我目前正在使用select()充当计时器。我有一个在循环内发生的网络接收操作,每隔几秒就需要进行一次处理操作。

结果,select()语句的超时不断变化 - 随着时间的推移逐渐减小到零,然后在3时重新启动。

rv = select(selectmonitor+1, &readnet, NULL, NULL, &helper.timeout());

当网络上出现问题时,语句会重复,并且helper.timeout()传递给它的值会减少。最终,该值将等于零或系统将超时,这将导致处理功能执行。但是,我注意到这是非常耗费资源的 - 必须不断计算helper.timeout()的值。当我试图每秒接收几千个数据包时,完成此操作所需的时间会导致数据包丢失。

我的新想法是使用SIGALRM来解决此问题。这将允许我设置一次计时器,然后在它被设置时作出反应。但是,我很困惑它会如何影响我的程序。当SIGALRM'熄灭'时,它将运行我指定的功能。但是,它将如何中断我现有的代码?一旦功能完成,我的现有代码(在while语句中)将如何恢复?

此外,似乎无法设置SIGALRM信号来调用类中的函数?它是否正确?我想我可以调用一个函数,它可以依次调用类中的函数。

感谢您提前获得任何帮助。

1 个答案:

答案 0 :(得分:1)

使用SIGALRM处理程序设置标志变量。

使用sigaction代替signal设置信号处理程序。不要设置SA_RESTART标志。使用SA_RESTART 设置时,您的select语句将被信号中断。你的选择将返回-1而errno将是EINTR。

由于信号可能在您的其他代码执行时发生,您也需要检查标志变量,可能在进入选择之前。

我刚刚提醒过,如果在检查标志之后和进入选择之前发生这种情况,可能会导致信号丢失。

为避免这种情况,您需要在进入while循环之前使用sigprocmask来阻止SIGALRM信号。然后,您使用pselect代替select。通过给pselect一个SIGALRM未屏蔽的信号掩码,信号最终会在选择期间中断,而不是在任何其他时间发生。