From: Roland (roland.schwarz_at_[hidden])
Date: 2004-01-14 13:14:26
(Darryl Green <Darryl.Green_at_[hidden]>) wrote:
> > From: Roland [mailto:roland.schwarz_at_[hidden]]
> > Say you have
> > a thread that sits waiting for IO, and then you want to send
> > it a command.
> > Say it is waiting for IO inside an object that is made thread
> > safe using
> > the monitor pattern. Now you want to send a command. The command
> > functions are secured by the monitor. How do you secure the function
> > that is waiting for IO? You would need to manually unlock and lock
> > the monitor somehow, while still not beeing able to honour a general
> > notify that would be able to force a state stange of the
> > object irrespective
> > how many thread are waiting on it in any combination of wait types.
> You want to block on IO ready inside an object protected by the monitor
> pattern? Why/how would you ever find yourself doing that? You mean that
> you want a "threadsafe" object with an interface protect by a monitor,
> but somehow you end up invoking a reactor within it? I don't think I
> understand your example.
Oh I see, I should have been more explicit.
I am talking about a passive object, that is protected by the monitor
pattern. One of its member functions first locks the monitor, and then
needs to call an IO function. Since this function might block I want
to unlock the monitor before actually calling into it.
Now assume a thread that calls into this member function and
ends blocking on IO.
A second thread now calls into another function of my object
and changes the state of the object. Further I assume, that the
first thread, that still is blocking on the other function (waiting
for IO) needs to honour the state change before continuing
to wait for the IO or abandon it.
So I need to wake up it somehow. And this cannot be done
by notify_one or notify_all. It can be done, I know, by other
means, but it isn't as elegant as would be using a single
notification mechanism throughout the object.
> > I must admit that I am a little biased now by the fact that I
> > was able to
> > write a small application that contains two classes that are derived
> > from thread and condition namely cancelable_thread and
> > cancelable_condition
> > that have been possible simply by _using_ boost.thread. For me this
> > was a strong indication of how complete the boost.thread primitives
> > already are. I wouldn't dare to tamper with them at all!
> > But, my classes still suffer from the problem that I cannot
> > sucessfully
> > cancel when a thread is inside the IO wait. Sure cancelling a
> > thread can
> > be tackled by other means (e.g like pthread) but cancelling
> > an object on
> > which you have a mix of different threads waiting?
> I'm not sure I follow just what you mean by "cancelling an object...".
Well, this relates to the monitor pattern to secure an object. I was
surprised a little bit because the issue I am talking about was not
addressed in the article (Monitor Object by Douglas C. Schmidt)
I read. (But perhaps I am missing something.)
Imagine a passive object secured by the monitor pattern. Now
let a number of threads block on the object.
How would you ever be able to delete the object now?
1) If you know every thread that currently blocks on the object,
you might shut down the threads in question, and delete the
object when finished. Thread canellation would be of help here
but knowing the threads is a mess.
2) If you know, that any thread that waits on the object, is
waiting on a single well known condition, you can design
the condition in such a way that it throws an exception to every
thread that is waiting. After all exceptions have been thrown
you know the object is safe for deletion. As an aditional
benefit the threads are informed that the object has gone
and can behave accordingly, either shut down itself or
try another strategy to reach their goal.
> It sounds to me like you have some conceptual framework in mind for
> active objects and you are having trouble implementing it using the
> existing thread library when the object is able to do IO? I don't have a
> good enough picture of your model to comment.
I hope from the above, it has become clear, that I am not speaking
about active objects.
> My point is simply that I don't believe there is an efficient way of
> unifying this in a library while remaining sufficiently portable. I'd be
> happy to be proved wrong! My suggestion is that a very basic/minimal
> "wake up" facility is
> i) portable
> ii) sufficient for most uses
> The wake-up facility can be implemented on top of various select-like
> interface and of course wfmo.
Interesting idea! Do you mean somehow getting a notify to wake up
I just tried to do it the other way round. I created a small active object,
that takes a refernce to a condition and a couple of Windows event
variables to wait for in its constructor. When any of the events gets signalled the
condition is notified in turn. To shutdown this object I rely on the
Windows messge queue, that is attached to every thread, by
sending it a WM_QUIT message from its destructor.
This is sufficient for my intended use, but I am still not satisfied,
because startup price for an active object is rather high, and
so is shutdown. Nevertheless, what I like about this solution
is its independence from the threading library.
What I have learned so far, in order to be independent from the
need to hack into the library,
I will need to have a separate thread. My first tought was to
use a thread per IO connection, but that is bad as it ends up
as 1 thread/client. Now I think about 1 thread per multiplexor
and let multiplexor be an active object.
But most likely this is not a new idea, and I go on eagerly
having a look at the links you have been posting.
> If you are interested in how various forms of io multiplexing work (or
> don't) on a variety of platforms a good place to start is
> Efficiency, portablity, elegance - pick any 2 (if you are lucky) :-)
All three of course! ;-)
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk