SIGALRM Timeout — How does it affect existing operations?

我的梦境 提交于 2019-12-08 12:46:00

问题


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.

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());

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.

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?

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.


回答1:


Use your SIGALRM handler to set a flag variable.

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.

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.



来源:https://stackoverflow.com/questions/3241634/sigalrm-timeout-how-does-it-affect-existing-operations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!