|
Home > Archive > Unix Programming > April 2004 > What's the cleanest way to wake a poll?
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 |
What's the cleanest way to wake a poll?
|
|
| DeMarcus 2004-04-21, 5:34 pm |
|
Hi,
I've got a poll() waiting for something to happen
on a couple of file descriptors. But if nothing
happens on those file descriptors I want to be
able to release the blocking poll(), and I don't
want to use the timeout feature.
So far I've tried to include a file descriptor I
got from a pipe() call, and then I can write something
to that pipe from another thread which will wake
the poll. But it feels a little dirty since I have
to write a byte I won't use, and then need to read it
off.
So my question is:
What is the cleanest way to wake a poll() from another
thread?
Thanks
Daniel Marcus
| |
| Frank Cusack 2004-04-21, 6:36 pm |
| On Wed, 21 Apr 2004 22:57:20 +0200 DeMarcus <nobody@tellus.orb> wrote:
> Hi,
>
> I've got a poll() waiting for something to happen
> on a couple of file descriptors. But if nothing
> happens on those file descriptors I want to be
> able to release the blocking poll(), and I don't
> want to use the timeout feature.
>
> So far I've tried to include a file descriptor I
> got from a pipe() call, and then I can write something
> to that pipe from another thread which will wake
> the poll. But it feels a little dirty since I have
> to write a byte I won't use, and then need to read it
> off.
>
> So my question is:
> What is the cleanest way to wake a poll() from another
> thread?
How about pthread_kill(th, SIGCONT)? You'd need to distinguish
EINTR from SIGCONT vs other EINTR's, pretty easy to do.
Why don't you want to use the timeout?
/fc
| |
| DeMarcus 2004-04-21, 7:36 pm |
|
Frank Cusack wrote:
> On Wed, 21 Apr 2004 22:57:20 +0200 DeMarcus <nobody@tellus.orb> wrote:
>
>
>
> How about pthread_kill(th, SIGCONT)? You'd need to distinguish
> EINTR from SIGCONT vs other EINTR's, pretty easy to do.
>
Good idea, but the problem with signals is that nobody knows
who they're aimed for. The main purpose is that they're aimed
for the whole process (or the whole thread in this case) which
forces the programmer to know exactly which signals are used
where. I can easily use it for my poll here as you suggested, but
that may give strange behaviour to other system calls that also
react on signals. Therefore I try to keep away from using signals.
Maybe I'm just not experienced enough.
> Why don't you want to use the timeout?
>
The timeout is only good if you're expecting something to happen
within a certain amount of time. Otherwise you have to wait for
X milliseconds, check a variable to see if we wanted to wake the
poll, and if not go back to the poll. The problem is that if we
want to wake the poll as fast as possible then we want X to be as
small as possible and we're approaching a bad spin loop.
> /fc
| |
| David Schwartz 2004-04-21, 7:36 pm |
|
"DeMarcus" <nobody@tellus.orb> wrote in message
news:4086fb6d$0$99625$57c3e1d3@news3.bahnhof.se...
> The timeout is only good if you're expecting something to happen
> within a certain amount of time. Otherwise you have to wait for
> X milliseconds, check a variable to see if we wanted to wake the
> poll, and if not go back to the poll. The problem is that if we
> want to wake the poll as fast as possible then we want X to be as
> small as possible and we're approaching a bad spin loop.
Why do you need to wake the poll as soon as possible? If you have file
descriptors, you probably want to poll on them anyway. Let whatever the
polling thread was going to do when you woke it up be done by another
thread.
DS
| |
| The King of Pots and Pans 2004-04-21, 9:34 pm |
| On Wed, 21 Apr 2004 at 20:57 GMT, DeMarcus spoke:
> So far I've tried to include a file descriptor I got from a pipe()
> call, and then I can write something to that pipe from another
> thread which will wake the poll. But it feels a little dirty since I
> have to write a byte I won't use, and then need to read it off.
That's the best way. I've used that technique for years on all kinds
of servers I've professionally written. Very good method.
--
The King of Pots and Pans
| |
| David Schwartz 2004-04-21, 11:34 pm |
|
"DeMarcus" <nobody@tellus.orb> wrote in message
news:4086e046$0$99623$57c3e1d3@news3.bahnhof.se...
> I've got a poll() waiting for something to happen
> on a couple of file descriptors. But if nothing
> happens on those file descriptors I want to be
> able to release the blocking poll(), and I don't
> want to use the timeout feature.
You could send a signal, but I don't recommend it.
> So far I've tried to include a file descriptor I
> got from a pipe() call, and then I can write something
> to that pipe from another thread which will wake
> the poll. But it feels a little dirty since I have
> to write a byte I won't use, and then need to read it
> off.
That's a very common way to do this.
> So my question is:
> What is the cleanest way to wake a poll() from another
> thread?
It really depends upon the exact circumstances of your application. For
many real world applications, believe it or not, the best solution is to
call 'poll' with an immediate timeout and then nanosleep before calling poll
again. This is especially true on Linux (only for some load profiles!) where
the cost of 'poll'ing with a timeout is very high.
DS
| |
| Frank Cusack 2004-04-22, 12:34 am |
| On Thu, 22 Apr 2004 00:53:10 +0200 DeMarcus <nobody@tellus.orb> wrote:
> Frank Cusack wrote:
>
>
> Good idea, but the problem with signals is that nobody knows
> who they're aimed for.
pthread_kill() certainly knows who a signal is aimed for.
> The main purpose is that they're aimed
> for the whole process (or the whole thread in this case) which
> forces the programmer to know exactly which signals are used
> where. I can easily use it for my poll here as you suggested, but
> that may give strange behaviour to other system calls that also
> react on signals. Therefore I try to keep away from using signals.
> Maybe I'm just not experienced enough.
Well, it won't give "strange" behavior, but it will give different
behavior. You'd have to clear SA_RESTART before poll() but you might
want to set it again so that read() (and all following syscalls) won't
have to deal with SIGCONT/EINTR.
So ignore what I said about SIGCONT and use a realtime signal instead.
I think you could also use a named pipe and have the other thread read
from it; poll() should test for writability. (I think that for named
pipes there must be a reader before poll() will return.) This is
probably not as good as reading a byte from a [unix] pipe. For one
thing, you have to make your reader go away without you actually
writing a byte. Or you have to actually write a byte which is back
where you started. I'm just thinking about other ways to do it, not
suggesting that this is a good way.
It'd be neat if you could write 0 bytes and have poll() wakeup. If you
control the kernel (eg if this is an embedded app) you can make this
work. But in that case I'd go with an rt signal anyway. You'd have
sufficient control over the environment that there's no longer an
argument against signals, yeah?
Maybe there's a way to manipulate a socket fd to wakeup poll() without
sending data. (I can't think of one, just throwing it out there.)
There's certainly nothing wrong with reading a byte from a pipe; it's
pretty clean if you are sure you aren't avoiding the timeout for the
wrong reasons.
>
> The timeout is only good if you're expecting something to happen
> within a certain amount of time. Otherwise you have to wait for
> X milliseconds, check a variable to see if we wanted to wake the
> poll, and if not go back to the poll. The problem is that if we
> want to wake the poll as fast as possible then we want X to be as
> small as possible and we're approaching a bad spin loop.
I assume you mean, if some OTHER event (not data available for read)
happens, you want to return from poll() as fast as possible. That
makes sense.
Then you should consider that using an rt signal should be faster than
the pipe method.
/fc
| |
| Michael Kerrisk 2004-04-22, 2:34 am |
| On Wed, 21 Apr 2004 15:12:41 -0700, Frank Cusack <fcusack@fcusack.com>
wrote:
>On Wed, 21 Apr 2004 22:57:20 +0200 DeMarcus <nobody@tellus.orb> wrote:
>
>How about pthread_kill(th, SIGCONT)? You'd need to distinguish
>EINTR from SIGCONT vs other EINTR's, pretty easy to do.
This technique will not work! SIGCONT is ignored unless the process
is STOPPED by a signal.
To the OP -- the solution you are already using is commonly used --
the overhead is probably insignificant, so why change it?
Cheers,
Michael
| |
| Andrei Voropaev 2004-04-22, 5:34 am |
| On 2004-04-21, DeMarcus <nobody@tellus.orb> wrote:
[...]
> So far I've tried to include a file descriptor I
> got from a pipe() call, and then I can write something
> to that pipe from another thread which will wake
> the poll. But it feels a little dirty since I have
> to write a byte I won't use, and then need to read it
> off.
Oh boy. Sending 1 byte on the pipe you consider "not-needed" and
"dirty". Sending signal to the thread (and signal will require much more
than 1 byte) you don't consider bad. Don't you notice that both
approaches serve the same purpose of "conveying information"? I would
say that sending 1 byte on the pipe is the cleanest and cheapest
solution. After all all sockets and file descriptors that poll watches
serve the purpose of conveying information. And receiving something is
also piece of information that you NEED 
Andrei
|
|
|
|
|