I have a mutlithreaded communication application where several threads wait
in select() for an UDP packet. The select() returns only when packet is
received or timeout expires. I need to be able to interrupt this select()
immediately and do other processing when some event occurs in another
thread. The select() timeout can be quite long (1 sec or so) and I don't
want to decrease it and check continuously if the event occured or not.
These events won't occur very often, but if they occur, I need immediate
reaction in the communicatin thread.
In Win32 it can be implemented using events and I can wait for UDP packet or
event in one call, or I can assign event to socket using WSAEventSelect().
Any advice how to implement this on Linux and pthreads?
I can see these possibilities:
1. using SIGURS1 or SIGUSR2 to interrupt select() but there can are
several identical threads waiting in select() and I need to interrupt only
one of them. It is also discuraged to use signals with pthreads.
2. opening unix-domain datagram socket for each thread and make the
select() wait on both of these sockets. The event thec can be signaled by
sending some data on this unix-domain socket.
3. the same could be probably done with pipes.
Thanks for any help,
Petr
What kind of help are you looking for? You have already listed
three possible solutions, and I can think of no better solution
than those you already listed.
In Linux it is AFAIK possible to send a signal to a single
thread, but implementations differs which is part of the reason
it is discuraged to use it.
Sockets as well as pipes can be used in your case. They don't
give you the same problems as signals, they are more flexible,
and they are better suited for use with select. In other words
using a socket or a pipe is a good solution. Both sockets and
pipes can be either named or anonymous. An anonymous pipe or
socket is preffered, but is only possible if it can be created
by a common ancestor. Otherwise a named pipe or socket is
needed.
Pipes are simple one direction byte streams.
Sockets are more complicated, they are two-way, they can IIRC
be either byte streams or packet streams, and they have other
features. Use a pipe if it suits your needs, but if a pipe is
too primitive for your problem, use a socket instead.
--
Kasper Dupont -- der bruger for meget tid på usenet.
For sending spam use mailto:aaa...@daimi.au.dk
for(_=52;_;(_%5)||(_/=5),(_%5)&&(_-=2))putchar(_);
Assuming that you're talking POSIX, you'd probably need pselect()
here [to fight races], I guess.
> > several identical threads waiting in select() and I need to interrupt only
> > one of them. It is also discuraged to use signals with pthreads.
> > 2. opening unix-domain datagram socket for each thread and make the
> > select() wait on both of these sockets. The event thec can be signaled by
> > sending some data on this unix-domain socket.
> > 3. the same could be probably done with pipes.
> >
> > Thanks for any help,
>
> What kind of help are you looking for? You have already listed
> three possible solutions, and I can think of no better solution
> than those you already listed.
Uhmm. I'd probably add to the list: "4. pthread_cancel()".
regards,
alexander.
On Unix, I usually use solution 3, but I would like to know
how to do this on WIN32. Do you use select() on WIN32, or
WaitForMultipleObjects()?
-SEan
You might look at pthread_kill to send the signal to a specific
thread. You will need some sort of mutex protected list of available
threads.
HTH
Brenton
On Win32 I use WaitForMultipleObejcts() or WSAWaitForMultipleEvents(). It
should be more efficient than using pipes and select(), at least I hope so.
Petr
I don't think that's likely, given the very low syscall latency in
Linux (unless you have a very large number of file descriptors in your
select()).
- Kevin.
>Hi,
>
>I have a mutlithreaded communication application where several threads wait
>in select() for an UDP packet. The select() returns only when packet is
>received or timeout expires. I need to be able to interrupt this select()
>immediately and do other processing when some event occurs in another
>thread. The select() timeout can be quite long (1 sec or so) and I don't
>want to decrease it and check continuously if the event occured or not.
>These events won't occur very often, but if they occur, I need immediate
>reaction in the communicatin thread.
>
I wonder why these other processing can't be done in another thread; after
all the program is already threaded, which means (if I'm not mistaken)
that each thread does not have to interrupt what ever it is currently doing
to something else.
Villy
In my case the thread behaviour is controlled by a lot of its internal state
variables. When I need to modify the behaviour of the thread in some way, I
do it from another thread by setting some of these internal variables
(synchronized via mutex).
The thread is basically this :
for(;;) {
pselect(...); // Wait for UDP packet with some timeout
pthread_mutex_lock(...);
if pselect() received something do recvfrom();
do some simple processing depending on the internal variables;
pthread_mutex_unlock(...);
}
If I don't interrupt pselect(), the new setting of internal variables can be
taken into account only after pselect() receives packet or timeout expires
but I need it immediately. I think using another thread wouldn't help me.
Petr
It has to be - the pipe/select technique does not work
at all on windows. The select call ignores the pipe fd.
Some windows calls look like their posix counterparts,
but this is a trap for the unwary.
-SEan
>"Petr Pecka" <petr....@ima.cz> writes:
>> I can see these possibilities:
>> 1. using SIGURS1 or SIGUSR2 to interrupt select() but there can are
>> several identical threads waiting in select() and I need to interrupt only
>> one of them. It is also discuraged to use signals with pthreads.
>> 2. opening unix-domain datagram socket for each thread and make the
>> select() wait on both of these sockets. The event thec can be signaled by
>> sending some data on this unix-domain socket.
>> 3. the same could be probably done with pipes.
>
>On Unix, I usually use solution 3, but I would like to know
>how to do this on WIN32. Do you use select() on WIN32, or
>WaitForMultipleObjects()?
While both techniques work in Windows, the preferred way is to use IO
completion ports. You simply send a message to the port and one of the
threads waiting on GetQueuedCompletionStatus would service it.
Ziv