SIGALRM超时 - 它如何影响现有操作? [英] SIGALRM Timeout -- How does it affect existing operations?

查看:272
本文介绍了SIGALRM超时 - 它如何影响现有操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前使用 select()作为计时器。

I am currently using select() to act as a timer. I have network receive operations which occur within a loop, and every few seconds a processing operation needs to occur.

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

As a result, the select() statement's timeout constantly changes -- decreasing to zero over time and then restarting at 3.

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

随着事情进入网络,语句重复,值由helper传递给它.timeout()减少。最终,值将等于零或系统将超时,这将导致处理函数执行。然而,我注意到这是相当资源密集型 - helper.timeout()的值必须不断计算。当我每秒尝试接收几千个数据包时,完成此操作所需的时间会导致数据包丢失。

As things come in on the network, the statement is repeated and the value passed to it by helper.timeout() decreases. Eventually, the value will either be equal to zero or the system will timeout, which will result in the processing function executing. However, I've noticed that this is quite resource intensive -- the value for helper.timeout() must be constantly calculated. When I am trying to receive a few thousand packets a second, the time it takes for this operation to be done results in packet loss.

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

My new idea is using SIGALRM to resolve this. This would allow me to set a timer once and then react when it is set off. However, I'm confused as to how it will affect my program. When SIGALRM 'goes off', it will run a function which I specify. However, how will it interrupt my existing code? And once the function is done, how will my existing code (within the while statement) resume?

它会出现不可能设置SIGALRM信号来调用类中的函数?它是否正确?我想我可以调用一个函数,它可以反过来调用类中的函数。

Also, it would appear its impossible to set the SIGALRM signal to call a function within a class? Is this correct? I imagine I can call a function, which can in turn call a function within a class..

感谢您提前的任何帮助。

Thanks for any assistance ahead of time.

推荐答案

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

Use your SIGALRM handler to set a flag variable.

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

Use sigaction instead of signal to set your signal handler. Do not set the SA_RESTART flag. With SA_RESTART not set your select statement will be interrupted by the signal. Your select will return -1 and errno will be EINTR.

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

Since the signal might happen while your other code is executing you will want to check the flag variable too, probably right before going into the select.

我只是提醒,这种模式可能会导致错过信号,如果发生只是检查标志后,只是在进入选择之前。

I was just reminded that this pattern can result in missing the signal, if it happens just after checking the flag and just before entering the select.

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

To avoid that, you need to use sigprocmask to block the SIGALRM signal before entering the while loop. Then you use pselect instead of select. By giving pselect a signal mask with SIGALRM unmasked, the signal will end up always interrupting during the select instead of happening at any other time.

这篇关于SIGALRM超时 - 它如何影响现有操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆