|
Home > Archive > Unix Programming > February 2005 > Suggestions of design (contd.)
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Suggestions of design (contd.)
|
|
| Kelvin Moss 2005-02-20, 6:19 pm |
| Hi group,
This is in continuation of my previous post some days back. I had asked
for suggestions/comments on the design I had in mind for several
processes trying to update some common counters.
I have finally zeroed down on shared memory and semaphore combination.
I need your feedback on another problem -- I need to check the value of
the counters in my master daemon (that creates the shared memory
region) every 1 second. What is the best way to do it ?
I have the following design in mind --
Register an alarm handler in the main program, alarm(1) and do
processing in the signal handler function. Use sigaction so that while
in signal handler no other sleep signal is encountered. What happens if
my signal handler takes more than 1 sec ? In that case I will not be
meeting the 1 sec requirement precisely.
I welcome your thoughts and suggestions.
Thank you.
| |
| Måns Rullgård 2005-02-20, 6:19 pm |
| "Kelvin Moss" <km_jr_usenet@yahoo.com> writes:
> Hi group,
>
> This is in continuation of my previous post some days back. I had asked
> for suggestions/comments on the design I had in mind for several
> processes trying to update some common counters.
>
> I have finally zeroed down on shared memory and semaphore combination.
> I need your feedback on another problem -- I need to check the value of
> the counters in my master daemon (that creates the shared memory
> region) every 1 second. What is the best way to do it ?
>
> I have the following design in mind --
>
> Register an alarm handler in the main program, alarm(1) and do
> processing in the signal handler function.
The usual advice is to do as little as possible in the signal handler.
> Use sigaction so that while in signal handler no other sleep signal
> is encountered. What happens if my signal handler takes more than 1
> sec?
Spending that much time in a signal handler is wrong.
> In that case I will not be meeting the 1 sec requirement precisely.
>
> I welcome your thoughts and suggestions.
>
> Thank you.
>
--
Måns Rullgård
mru@inprovide.com
| |
| Kelvin Moss 2005-02-20, 6:19 pm |
|
M=E5ns Rullg=E5rd wrote:
> "Kelvin Moss" <km_jr_usenet@yahoo.com> writes:
> Spending that much time in a signal handler is wrong.
hmm...that sounds correct to me. The reason I suspect that 1 second
requirement will be violated is because the daemon needs to get hold of
semaphore before it does processing in the handler.
So what should be the approach that I should be taking ?
Thanks again.
| |
| Måns Rullgård 2005-02-20, 6:19 pm |
| "Kelvin Moss" <km_jr_usenet@yahoo.com> writes:
> Måns Rullgård wrote:
>
>
> hmm...that sounds correct to me. The reason I suspect that 1 second
> requirement will be violated is because the daemon needs to get hold of
> semaphore before it does processing in the handler.
It's simply illegal to do that kind of work in a signal handler. You
have to design your application in such a way that the signal handler
can do something simple, such as setting a flag, causing the program
to take the appropriate action when the signal handler returns.
If you want to repeat something with 1 second intervals, and the
something can take more than 1 second, you have a problem no matter
how you design the program. The only options are to ignore some runs,
or postpone them. Which is more sensible depends on what you are
doing, and why.
--
Måns Rullgård
mru@inprovide.com
| |
| Kelvin Moss 2005-02-20, 6:19 pm |
| >It's simply illegal to do that kind of work in a signal handler.
> You have to design your application in such a way that the signal
>handler can do something simple, such as setting a flag, causing the
>program to take the appropriate action when the signal
>handler returns.
I understand your point but I can not somehow get to the correct
solution. The problem is something like this --
My daemon process needs to read the shared memory region every 1 sec
and also flush it after it has read it. The 1 second requirement gets
the signal handler into picture. The need to flush the shared memory
region for the following accesses into the shared memory, brings the
rquirement to lock it. Had the requirement to not flush it had been
there I could have lived without grabbing the semaphore.
I know that having statements like printf etc in signal handler is
disastrous since it in turn could be calling malloc etc. Is there any
danger which I am overlooking when I grab semaphore and do some
processing in the signal handler ?
As always your comments are most welcome.
Thanks.
| |
| Måns Rullgård 2005-02-20, 6:19 pm |
| "Kelvin Moss" <km_jr_usenet@yahoo.com> writes:
>
> I understand your point but I can not somehow get to the correct
> solution. The problem is something like this --
>
> My daemon process needs to read the shared memory region every 1 sec
> and also flush it after it has read it. The 1 second requirement gets
> the signal handler into picture. The need to flush the shared memory
> region for the following accesses into the shared memory, brings the
> rquirement to lock it. Had the requirement to not flush it had been
> there I could have lived without grabbing the semaphore.
What is the program doing otherwise? If it spends most of the time
waiting on a socket or similar, you could use select() with a timeout
to get a chance at doing other things every now and then.
> I know that having statements like printf etc in signal handler is
> disastrous since it in turn could be calling malloc etc. Is there any
> danger which I am overlooking when I grab semaphore and do some
> processing in the signal handler ?
If you only use functions that are explicitly mentioned as safe to
call from a signal handler, you'll be fine. I'm not sure about the
semaphore functions, but the safe functions are the minority out
there.
--
Måns Rullgård
mru@inprovide.com
| |
| Kelvin Moss 2005-02-20, 6:19 pm |
|
M=E5ns Rullg=E5rd wrote:
> "Kelvin Moss" <km_jr_usenet@yahoo.com> writes:
>
the[vbcol=seagreen]
sec[vbcol=seagreen]
gets[vbcol=seagreen]
memory[vbcol=seagreen]
the[vbcol=seagreen]
>
> What is the program doing otherwise? If it spends most of the time
> waiting on a socket or similar, you could use select() with a timeout
> to get a chance at doing other things every now and then.
>
any[vbcol=seagreen]
>
> If you only use functions that are explicitly mentioned as safe to
> call from a signal handler, you'll be fine. I'm not sure about the
> semaphore functions, but the safe functions are the minority out
> there.
>=20
> --=20
> M=E5ns Rullg=E5rd
> mru@inprovide.com
| |
| Kelvin Moss 2005-02-20, 6:19 pm |
|
M=E5ns Rullg=E5rd wrote:
> "Kelvin Moss" <km_jr_usenet@yahoo.com> writes:
> What is the program doing otherwise? If it spends most of the time
> waiting on a socket or similar, you could use select() with a timeout
> to get a chance at doing other things every now and then.
Yes, a call similar to select can help me here.
Well the program is meant for SNMP statistics. So it is something like
this in short --
1=2E The SNMP subagent creates a shared memory region and semaphore
2=2E It registers a handler so that it can know the state of shared
memory every second. It needs to flush the shared memory too after it
has read it.
3=2E If a snmpget request comes then it needs to answer the desired
value.
I am using NetSNMP library (Linux).
So the way we wait for snmpget requests is --
while(1) {
/* if you use select(), see snmp_select_info() in snmp_api(3) */
/* Some processing */
agent_check_and_process(1); /* 0 =3D=3D don't block */
}
agent_check_and_process api blocks till an snmpget is encountered or an
alarm condition occurred. I can use the latter to do some processing
from time to time.
any[vbcol=seagreen]
>
> If you only use functions that are explicitly mentioned as safe to
> call from a signal handler, you'll be fine. I'm not sure about the
> semaphore functions, but the safe functions are the minority out
> there.
Yes.
Thanks for all your inputs. I really appreciate them.
| |
| Michael B Allen 2005-02-20, 6:20 pm |
| On Fri, 18 Feb 2005 05:35:38 -0500, Kelvin Moss wrote:
> Register an alarm handler in the main program, alarm(1) and do
> processing in the signal handler function. Use sigaction so that while
Signals are evil. I never use them unless absolutely necessary
(e.g. process control).
> in signal handler no other sleep signal is encountered. What happens if
> my signal handler takes more than 1 sec ? In that case I will not be
> meeting the 1 sec requirement precisely.
Use select(2). Create a pipe and have your master daemon call select(2)
with a timeout of 1 sec. That way your children who inherit the pipe
can also write a byte to it [1] as a "signalling" mechanism. Down the
line you'll probably realize you need that sort of thing anyway.
Mike
[1] Just make sure you don't write to the pipe more than you read from
it or your children will block when the pipe fills up.
| |
|
| Kelvin Moss wrote:
> Måns Rullgård wrote:
>
>
>
>
>
> Yes, a call similar to select can help me here.
> Well the program is meant for SNMP statistics. So it is something like
> this in short --
>
> 1. The SNMP subagent creates a shared memory region and semaphore
> 2. It registers a handler so that it can know the state of shared
> memory every second. It needs to flush the shared memory too after it
> has read it.
> 3. If a snmpget request comes then it needs to answer the desired
> value.
>
Flush shared memory ?
Syntax error.
> I am using NetSNMP library (Linux).
>
> So the way we wait for snmpget requests is --
>
> while(1) {
> /* if you use select(), see snmp_select_info() in snmp_api(3) */
> /* Some processing */
>
> agent_check_and_process(1); /* 0 == don't block */
> }
>
Avoid blocking on read(), especially while holding locks/semafores.
Use select() and non-blocking read() in the fragment above.
manipulate the fd_set to service only the fds that can be
serviced without blocking on a semafore. (or skip the fd if
semafores cannot be obtained)
> agent_check_and_process api blocks till an snmpget is encountered or an
> alarm condition occurred. I can use the latter to do some processing
> from time to time.
>
>
>
>
Not just printf/malloc et.al. *any* shared resource.
Avoid.
[vbcol=seagreen]
>
> any
>
Sharing resources && signalhandlers don't mix easily.
You'd have to jump through hoops to avoid the signalhandler
beeing called when some needed resource (semafore) is held
by another process. Avoiding processing in signalhandlers
alltogether seems a sane design choice, IMHO.
[vbcol=seagreen]
>
>
> Yes.
>
> Thanks for all your inputs. I really appreciate them.
>
Not just the functions you call.
Your own program's data and resources as well.
HTH,
AvK
|
|
|
|
|