boost::thread and class d'tor

C

Chameleon

Why this strange output?
Why so many d'tor calls?

The code:
----------------------------------------------------------
#include <cstdio>
#include <boost/thread/thread.hpp>

class A
{
boost::thread *thread;
public:
A() : thread(0) {
printf("ctor\n");
}
~A() {
printf("dtor enter\n");
join();
//delete thread;
printf("dtor leave\n");
}

void createThread() {
printf("create enter\n");
thread = new boost::thread(*this);
printf("create leave\n");
}

void operator()() {
printf("start thread: %d\n", thread);
delete thread; thread = 0;
printf("leave thread\n");
}

void join() { if (thread) thread->join(); }
};

int main() {
A a;
a.createThread();
a.join();
return 0;
}
----------------------------------------------------------

The output:
----------------------------------------------------------
ctor
create enter
dtor enter
dtor leave
dtor enter
dtor leave
dtor enter
dtor leave
dtor enter
dtor leave
dtor enter
dtor leave
dtor enter
dtor leave
dtor enter
dtor leave
start thread: 0
dtor enter
dtor leave
leave thread
dtor enter
dtor leave
create leave
dtor enter
dtor leave
dtor enter
dtor leave
 
P

Pete Becker

Why this strange output?
Why so many d'tor calls?

The immediate answer is that class A's copy constructor isn't
instrumented, so the output doesn't show copy construction of objects
that later get destroyed.

The more useful answer is, you should probably ask the Boost folks. It
certainly looks like there are more objects being created than are
necessary.
 
J

James Kanze

On 2008-01-07 08:21:16 -0500, Chameleon <[email protected]> said:
The immediate answer is that class A's copy constructor isn't
instrumented, so the output doesn't show copy construction of objects
that later get destroyed.
The more useful answer is, you should probably ask the Boost
folks. It certainly looks like there are more objects being
created than are necessary.

Possibly, but if his compiler doesn't implement RVO or NRVO,
there will be quite a few.

More important, perhaps, is the fact that all of these instances
point to the same instance of boost::thread. And that setting
it to null after the delete in the operator()() isn't going to
null the pointer to in the instance in main. If the thread
actually starts immediately, and operator()() gets executed
before the code gets to the a.join() in main, he's going to call
join() on a deleted object (undefined behavior). And if the
thread with main executes first, then in the operator()(), he's
going to destruct a boost::thread on which another thread is
waiting for a join---I'm not sure what that's supposed to do
either.

So just instrumenting the copy constructor is not enough. He's
going to have to think about joinability, and either use a local
boost::thread object in the createThread function (detached
thread) or use a boost::shared_ptr rather than a raw pointer to
the boost::thread in his object (and of course, in neither case
delete the boost::thread manually himself).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top