Re: What's the connection between objects and threads?
"Szabolcs Ferenczi" <szabolcs.ferenczi@gmail.com> wrote in message
news:f47e35cb-44b8-4072-bf8b-42f05c6dc4ea@d1g2000hsg.googlegroups.com...
On May 21, 8:08 pm, "Chris Thomasson" <cris...@comcast.net> wrote:
[...]
I showed you one reason why its not a good idea to spawn threads from
ctors.
You showed nothing else but that you can hack C++ even in sequential
mode so that the compiler cannot catch your misuse. That was it.
Congratulations.
The sample code showed exactly how the OP could of shot himself in the foot.
See, I used the 'call_abstract_virtual_indirect()' function to make the
compiler shut up because its directly analogous to calling
'pthread_create()' and providing it with an entry function which calls the
virtual function used to represent the thread entry for the derived class.
The OP mentioned that he wanted to use a threading base class. I warned him
that starting threads in ctors can be dangerous because of a race-condition.
On the other hand, you basically told him that threads in ctors is fine. You
totally forgot to mention any of the caveats. Why did you do that?
I could show you some others, but I suspect that you already know them.
See,
I think you know that starting threads from ctors is "generally" a bad
idea,
and your just doing a little trolling for some reason. Oh well.
I taked about disciplined use. Of course, that is not for hackers like
you.
:^/
Hackers also do not know that there are computational models where
objects and processes are unified into active objects. And that
exactly means that the object starts its activity right after
initialising its internal state.
Right. It starts the thread __after__ initializing its internal state. An
objects state is not fully initialized until in has been completely
constructed. This means that an object is not technically initialized until
it constructor function has returned from the point of invocation; IMHO,
this is how C++ operates.
If you create the thread in the ctor that means that it makes up part of its
initialization procedure, and it could end up operating on an object whose
ctor has not completely finished yet; this is a race-condition. Generally,
you want to pass objects to threads __after__ the initialization has been
completely fulfilled...
So it is not at all new concept. Ok,
you and your friends cannot know that due to lack of education in
concurrent programming.
Why do you need to start threads in ctors? That can be dangerous. However,
if your careful, it can be done. Here is a simple example:
<pseudo-code sketch>
______________________________________________________________
class thread_base {
virtual void on_entry() = 0;
public:
void start() { ... };
void join() { ... };
};
class active_object : public thread_base {
public:
active_object() {
// construct
}
private:
void on_entry() {
// running
}
virtual void on_object_state_shift() = 0;
};
template<typename T>
struct run {
T m_object;
run() { m_object.start(); }
~run() throw() { m_object.join(); }
};
class my_object : public active_object {
void on_object_state_shift() {
// whatever...
}
};
int main() {
{
run<my_object> mobj;
}
return 0;
}
-- or --
int main() {
{
my_object mobj;
mobj.start();
mobj.join();
}
return 0;
}
______________________________________________________________
This works fairly well because the run<T> template has nothing to do with
any active object state. It only ensures that the object has been fully
constructed __before__ the thread which drives it has been created...
Any thoughts?