[muscle] Re: Thread-safe queues
- From: Jeremy Friesner <jaf@xxxxxxxxxxxx>
- To: muscle@xxxxxxxxxxxxx
- Date: Mon, 21 Feb 2005 10:23:59 -0800
Hi Paal,
Let me answer your questions in reverse order... :^)
> I also want to use SendMessageToSessions() in another thread than the one
> where my Win32MessageTransceiverThread-loop is running.
The MessageTransceiverThread class is designed to co-ordinate just two
threads: the I/O thread which the MessageTransceiverThread class creates and
holds internally, and the user thread that is holding the
MessageTransceiverThread object (i.e. your Win32 thread in this case).
Trying to call methods directly on the MessageTransceiverThread object from a
third thread is probably not a good idea. A better technique would be to have
the third thread send a MessageRef to your Win32 thread, and then your Win32
thread could forward that MessageRef on to the MessageTransceiverThread (by
calling SendMessageToSessions() on it).
A good way to send MessageRefs between threads is to implement your threads
using the MUSCLE Thread class -- that way, the thread-safe MessageRef queues
are all set up and handled for you. (Note that MessageTransceiverThread
itself subclasses the Thread class, so MessageTransceiverThread is an example
of how to do this -- it subclasses the Thread class to create a thread that
does network I/O, but if you need to have threads that do other things, you
can just subclass from the Thread class directly, and override
MessageReceivedFromOwner() with code to handle the MessageRefs that you send
to that thread. Then messaging is easy -- your main thread just calls
SendMessageToInternalThread() to send a MessageRef to the internal thread,
and the internal thread can call SendMessageToOwner() to send a MessageRef
back to the main thread. (One caveat is that if you want your Win32 thread
to be woken up to receive the MessageRef from your internal thread, you will
need to override Thread::SignalOwner() to call SetEvent() or
PostThreadMessage(), similar to what is done in
Win32MessageTransceiverThread::SignalOwner())
On Monday 21 February 2005 05:31, Paal Grana wrote:
> Is it possible to use a Queue object from two different threads like this:
[...]
> I want to send data from one thread to another (producer - consumer )
> using a Queue.
No -- the Queue class wasn't designed to be thread safe. (Same goes for
Hashtable and Message, btw). If for some reason you need to access a Queue's
methods directly from multiple threads, you will need to serialize access to
the Queue to avoid data corruption.
> Will I have to use EnterCriticalSection() around RemoveHead/AddTail?
You could use that, but a better solution would be to use a muscle Mutex
object and call Lock()/Unlock() on it. (And a better solution than that
would be to use the Thread class as described above... or at least examine
the MessageRef-handling code in the Thread class to get a feel for what needs
to be done)
> I have run into problems doing this and the reason seems to be
> multi-threading related.
Multi-threading is tricky to get 100% correct, so good luck... my advice is to
re-use muscle's threading APIs as much as possible, as they have already been
debugged and tested and work well on all supported platforms (AFAIK).
Jeremy
- References:
- [muscle] Thread-safe queues
- From: Paal Grana
Other related posts:
- » [muscle] Thread-safe queues
- » [muscle] Re: Thread-safe queues
- [muscle] Thread-safe queues
- From: Paal Grana