I created a thread class TSPThread in my application which provides a
virtual "run()" method so other classes can easily access threads by
inheriting this thread class. Now my problem lies in the destructor of the
thread class, how do i best wait before I call:
if(m_pThread > 0) pthread_cancel(m_pThread);
pthread_mutex_destroy(&mutex_single);
And how would I signal from the chlid class?
Thanks for hints & tips!
Ron
--
weeks of software enineering safe hours of planing ;)
> Hi,
>
> I created a thread class TSPThread in my application which provides a
> virtual "run()" method so other classes can easily access threads by
> inheriting this thread class. Now my problem lies in the destructor of the
> thread class, how do i best wait before I call:
> if(m_pThread > 0) pthread_cancel(m_pThread);
> pthread_mutex_destroy(&mutex_single);
>
> And how would I signal from the chlid class?
mh, I got a version that should be workingf fine:
I have a virtual method SetStopFlag that is setting a bool variable to true
when the thread loop function exits and this is returned with
GetStopFlag().
This seems to be working fine in my TSPThread destructor:
while(m_pThread > 0 && nCount < 800 && !GetStopFlag())
{
usleep(10000);
nCount++;
}
//OUTPUT(cout << "Exit after secs: " << ((float)nCount)/100<<endl;)
if(m_pThread > 0) pthread_cancel(m_pThread);
pthread_mutex_destroy(&mutex_single);
but after the destroy, one step further, GDB (or rather KDevelop) is giving
me this message: "Program received signal SIGABRT (Aborted)" and stops any
further execution (shutting down of other threads).
Aany idea what I could be doing wrongly?
Help would be appreciated!
I don't quite see what you are doing. Why do you call pthread_cancel()
at all? That's a violent way to stop a thread. The normal way is for
the thread to call pthread_exit() or to return from the start routine
passed to pthread_create(). A destructor waiting for the thread to
terminate can use pthread_join().
> mh, I got a version that should be workingf fine:
> I have a virtual method SetStopFlag that is setting a bool variable to true
> when the thread loop function exits and this is returned with
> GetStopFlag().
A thread loop - picking up tasks posted to a task queue? Then the
destructor could set a flag which means it wants the thread to exit,
then call pthread_join() to wait for that. The thread loop would check
and obey this flag before looking for the next task, or maybe run any
remaining tasks and then obey the flag if it is set.
> This seems to be working fine in my TSPThread destructor:
>
> while(m_pThread > 0 && nCount < 800 && !GetStopFlag())
> {
> usleep(10000);
> nCount++;
> }
usleep? You are wondering when and how to kill a thread which refuses
to die? Then instead of pthread_join() it might be better to detach the
thread and have it call pthread_signal() just before exiting, to inform
the destructor it is about to die. The destructor can wait for the
signal with pthread_cond_timedwait(), and if it times out, _then_ pound
the thread with a pthread_cancel() call.
> //OUTPUT(cout << "Exit after secs: " << ((float)nCount)/100<<endl;)
> if(m_pThread > 0) pthread_cancel(m_pThread);
> pthread_mutex_destroy(&mutex_single);
You didn't mention what these variables are for, so it's a bit hard to
guess is the code is correct.
--
Hallvard
> Aany idea what I could be doing wrongly?
you shouldn't call virtual function from a c'tor or a d'tor because you
will call that functions from the base class, not from the derived
class. The derived part of the class will already be destructed when the
base class destructor is called. So the thread have to be stopped,
before the base class destructor is called.
A thread as a base class is really not the best design (what do you have
to do in case you want to start more than one thread per class
instance?). Have a look at boost/threads for a proper design. There is
thread is just a handle to a thread executing a function.
You are testing m_pThread more than one time, this suggests that you are
setting m_pThread from some other thread, but there is not proper
synchronization in your code.
best regards
Torsten
--
kostenlose Wirtschaftssimulation: http://www.financial-rumors.de
Does a file get destroyed when the file-class instance is destroyed?
Seriously, both a file class and a thread class ARE not the according thing
but they represent a HANDLE TO the thing. That means that you can't
hardcode the way to shut down a thread from the baseclass. The way to do
that strongly depends on the work the actual thread is doing, sometimes a
flag is used, sometimes a special request in a queue.
BTW: I'd use Boost.Thread instead of rolling my own or at the very least
take a look at it. Instead of deriving from a thread baseclass, it only
requires something that can be called like a function, either a function
pointer or functor, an object with a function call operator. If you want to
pass further information in, you either use a functor or use bind() or
similar means to construct one. No further dependency on a thread class
exists, so you don't have to modify the code just to call it from a
different thread.
BTW: pthread_cancel is straight out in a C++ program. The problem with this
function is that it terminates the thread without unwinding the stack, not
calling destructors which then don't release resources. Those resources are
typically file handles and memory, but can also be locks. You don't want
that.
> And how would I signal from the chlid class?
I'm not sure what you mean, you could simply return from the entry function
and some other thread could pthread_join() to wait for that or any other
way that you use for communication between threads.
Uli
[ removed good advice to look at other art ]
>BTW: pthread_cancel is straight out in a C++ program. The problem with this
>function is that it terminates the thread without unwinding the stack, not
>calling destructors which then don't release resources. Those resources are
>typically file handles and memory, but can also be locks. You don't want
>that.
Actually, any implementation these days that doesn't correctly unwind
the stack on cancellation could easily be called "hopelessly broken".
Note that pthread cleanup handlers require an unwind-like activity,
though some implementations did odd things like separate linked lists.
While it's not required by any standard, I believe most current pthreads
implementations that also have C++ support do this unwinding in a reasonable
fashion.
--
Steve Watt KD6GGD PP-ASEL-IA ICBM: 121W 56' 57.5" / 37N 20' 15.3"
Internet: steve @ Watt.COM Whois: SW32-ARIN
Free time? There's no such thing. It just comes in varying prices...