How is deadlock occuring in the below code? - concurrency

I am trying to understand deadlock from Oracle's website deadlock but not sure why & when does two custom threads goes into deadlock condition.
package com.geekthread.java.threads;
public class DeadLock {
static class Friend {
private final String name;
public Friend(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public synchronized void bow(Friend bower) {
System.out.format("%s: %s"
+ " has bowed to me!%n",
this.name, bower.getName());
bower.bowBack(this);
}
public synchronized void bowBack(Friend bower) {
System.out.format("%s: %s"
+ " has bowed back to me!%n",
this.name, bower.getName());
}
public static void main(String[] args) {
final Friend alphonse =
new Friend("Alphonse");
final Friend gaston =
new Friend("Gaston");
//holds lock for alphonse
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
//holds lock for gastone
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
}
}
}
Please correct my understanding of the above program:-
1.) Holds lock for alphonse
new Thread(new Runnable() {
public void run() { alphonse.bow(gaston); }
}).start();
2.) Holds lock for gastone
new Thread(new Runnable() {
public void run() { gaston.bow(alphonse); }
}).start();
I have tried to remove synchronized keyword from the bowback that doesn't ends in a deadlock situation i.e. the program execution completes and program terminates after execution.
Thanks

Every object has a lock associated with it, also known as an implicit lock or monitor lock. When synchronized is used on a method as in your example, the thread will try to take the lock associated with that method's object. So the thread that runs alphonse.bow(gaston); will take the lock associated with the alphonse object.
At roughly the same time, the thread that runs gaston.bow(alphonse); will take the lock associated with the gaston object.
So you have the alphonse thread holding the alphonse object's lock and the gaston thread holding the gaston object's lock.
When alphonse now tries to execute bower.bowBack(this);, note that 'bower' refers to the gaston object. So alphonse is trying to execute the bowBack method of the gaston object. Since the bowBack method is synchronized, alphonse needs to get the gaston object lock to proceed. But of course the gaston thread already has the gaston object lock!
So alphonse is trying to execute gaston's bowBack method, but can't because it can't get the gaston object lock.
At the same time, gaston has the same problem. He needs to call alphonse's bowBack method, but the alphonse thread already has the alphonse object lock.
So each thread has one lock and is trying to get the lock that the other thread already has and neither can proceed - a classic deadlock scenario..
Edit: Removing 'synchronized' from bowBack prevents the deadlock, as you discovered, because now there is nothing preventing the alphonse thread from calling gaston's bowBack method - alphonse no longer needs to obtain the gaston object lock that gaston is holding. The same logic applies in reverse to gaston, who can also proceed.

I'm definitly not an expert in Java but my guess would be:
Since the class Friend is static, the methods of class Friend are static. Thus those methods lock the class itself and not the objects of the class.
This should provide more insight: 8.4.3.6, 'synchronized Methods'

Related

Waiting for an asynchronous method to finish

In my multi-threaded programs I often use an approach like shown below to synchronize access to data:
class MyAsyncClass
{
public: // public thread safe interface of MyAsyncClass
void start()
{
// add work to io_service
_ioServiceWork.reset(new boost::asio::io_service::work(_ioService));
// start io service
_ioServiceThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &_ioService)));
}
void stop()
{
_ioService.post(boost::bind(&MyAsyncClass::stop_internal, this));
// QUESTION:
// how do I wait for stop_internal to finish here?
// remove work
_ioServiceWork.reset();
// wait for the io_service to return from run()
if (_ioServiceThread && _ioServiceThread->joinable())
_ioServiceThread->join();
// allow subsequent calls to run()
_ioService.reset();
// delete thread
_ioServiceThread.reset();
}
void doSometing()
{
_ioService.post(boost::bind(&MyAsyncClass::doSometing_internal, this));
}
private: // internal handlers
void stop_internal()
{
_myMember = 0;
}
void doSomething_internal()
{
_myMember++;
}
private: // private variables
// io service and its thread
boost::asio::io_service _ioService;
boost::shared_ptr<boost::thread> _ioServiceThread;
// work object to prevent io service from running out of work
std::unique_ptr<boost::asio::io_service::work> _ioServiceWork;
// some member that should be modified only from _ioServiceThread
int _myMember;
};
The public interface of this class is thread-safe in the sense that its public methods can be called from any thread and boost::asio::io_service takes care that access to the private members of this class are synchronized. Therefore the public doSomething() does nothing but posting the actual work into the io_service.
The start() and stop() methods of MyAsyncClass obviously start and stop processing in MyAsyncClass. I want to be able to call MyAsyncClass::stop() from any thread and it should not return before the uninitialization of MyAsyncClass has finished.
Since in this particular case I need to modify one of my private members (that needs synchronized access) when stopping, I introduced a stop_internal() method which I post to the io_service from stop().
Now the question is: How can I wait for the execution of stop_internal() to finish inside stop()? Note that I cannot call stop_internal() directly because it would run in the wrong thread.
Edit:
It would be nice to have a solution that also works if MyAsyncClass::stop() is called from the _ioServiceThread, so that MyAsyncClass can also stop itself.
I just found a very nice solution myself:
Instead of removing work (resetting _ioServiceWork) in stop(), I do it at the end of stop_internal(). This means that _ioServiceThread->join() blocks until stop_internal() has finished - exactly what I want.
The nice thing about this solution is that it doesn't need any mutex or condition variable or stuff like this.

C++ std::timed_mutex has recursive behaviour

i have a problem. i want to use a mutex for my program. so what happens is this:
i am constructing an object that holds a std::timed_mutex. on creation this object locks the mutex because it should be unlocked later on. the same thread that created the mutex should now wait for that mutex while some other thread does work in the background. joining the thread is no option.
class A{
std::timed_mutex mutex;
A(){
mutex.lock();
}
bool waitForIt(int timeout){
if(mutex.try_lock_for(std::chrono::milliseconds(timeout))){
mutex.unlock();
return true;
}else{
return false;
}
}
}
when calling waitForIt from the same thread the program just goes through and instantly gets a false, totally ignoring the timeout.(yes its intended to unlock the mutex afterwards. it should mime something like an event so every thread waiting gets through)
so in the documentation it says this mutex has a nonrecursive behaviour. but testing revealed that for example i can use the .lock() multiple times from the same thread without getting blocked. i also can use try_lock_for multiple times and every time get true!!! if i once use lock before the try_lock_fors i always get false. sadly i need something that also blocks the same thread that locked the mutex. and i have no idea what to use. im programming on linux btw. so maybe there is a native solution?
also i didnt find a semaphore in the std libs.i could use that instead of the mutex. using my own implementation would be possible but i dont know how to make my own semaphore. any ideas?
as people dont seems to understand that its not that simple:
class IObservable : public IInterface{
private:
std::list<std::shared_ptr<IObserver>> observers;
public:
virtual ~IObservable(){}
void AddObserver(std::shared_ptr<IObserver> observer);
void RemoveObserver(std::shared_ptr<IObserver> observer);
void ClearObservers();
void TellCompleted(bool wasCanceled = false, std::shared_ptr<void> status = 0);
TYPEIDHASHFUNC(IObservable)
};
IObservable is the thing that threads can add observers to. the thing deriving from IObservable calls the method TellCompleted at the end of its actions.
class IObserver : public IInterface{
public:
virtual ~IObserver(){}
virtual CompleteResult Complete(bool wasCanceled, std::shared_ptr<void> status) = 0;
virtual bool WaitForCompletion(int timeoutInMs) = 0;
virtual bool IsCompleted() const = 0;
virtual bool WasCanceled() const = 0;
virtual std::shared_ptr<void> GetStatus() const = 0;
virtual void Reset() = 0;
TYPEIDHASHFUNC(IObserver)
};
IObserver are the observer that can be added to a IObservable. if IObservable completes the method Complete gets called on each observer that was added to the observable
class BasicObserver : public IObserver{
private:
bool isCompleted;
bool wasCanceled;
CompleteResult completeResult;
std::shared_ptr<void> status;
std::timed_mutex mutex;
public:
BasicObserver(CompleteResult completeResult);
~BasicObserver();
CompleteResult Complete(bool wasCanceled, std::shared_ptr<void> status);
bool WaitForCompletion(int timeoutInMs);
bool IsCompleted() const;
bool WasCanceled() const;
std::shared_ptr<void> GetStatus() const;
void Reset();
TYPEIDHASHFUNC(BasicObserver)
};
this is one implementation of an observer. it holds the mutex and implements the WaitForCompletion with the timeout. WaitForCompletion should block. when complete is being called its mutex should be unlocked. when the timeout runs WaitForCompletion returns false
BasicObserver::BasicObserver(CompleteResult completeResult):
isCompleted(false),
wasCanceled(false),
completeResult(completeResult)
{
std::thread createThread([this]{
this->mutex.lock();
});
createThread.join();
}
BasicObserver::~BasicObserver(){
}
CompleteResult BasicObserver::Complete(bool wasCanceled, std::shared_ptr<void> status){
this->wasCanceled = wasCanceled;
this->status = status;
isCompleted = true;
mutex.unlock();
return completeResult;
}
bool BasicObserver::WaitForCompletion(int timeoutInMs){
std::chrono::milliseconds time(timeoutInMs);
if(mutex.try_lock_for(time)){
mutex.unlock();
return true;
}else{
return false;
}
}
bool BasicObserver::IsCompleted() const{
return isCompleted;
}
bool BasicObserver::WasCanceled() const{
return wasCanceled;
}
std::shared_ptr<void> BasicObserver::GetStatus() const{
return status;
}
void BasicObserver::Reset(){
isCompleted = false;
wasCanceled = false;
status = 0;
std::chrono::milliseconds time(250);
mutex.try_lock_for(time); //if this fails it might be already resetted
}
//edit: solved by using a semaphore instead (sem_t from semaphore.h)
You could use a condation_variable, specifically wait_until or wait_for.
I would consider a redesign of your locking structure.
Why not have the lock held by the main thread, and when event x happens you unlock it. If you need to block for a duration I would just make the thread sleep.
Have all working threads blocking on the mutex trying to acquire the lock, if they need to run concurrently have them immediately release the lock once they acquire it.
maybe use a second mutex to emulate event x.
i want to setup the lock from thread 1 then start a thread 2 that
does something (wait for input from hardware in this case) and then
wait for the mutex in thread 1. thread 2 then unlocks the mutex when i
press the switch on the hardware. im using some kind of observer
pattern. so i have something observable where i add an observer to(in
this case the class A is the observer). at some point the observable
tells all added observers that it completed its task and thus unlocks
the mutex. as we have hardware here it could be that the hardware
locks up or a sensor doesnt work. so i NEED a timeout. – fredlllll 3
mins ago
EDIT - Maybe this would work?
Hold lock in thread 1, after thread 2 gets input block on that lock. Have thread 1 release the lock after timeout duration, maybe sleep a little to allow threads through then acquire the lock again. Have thread 2 release lock 1 then begin blocking on a second mutex after acquiring mutex 1, have hardware switch unlock mutex 2 which causes thread 2 to lock mutex2 then unlock mutex 2. Have hardware switch acquire mutex 2 again.

C++11 thread doesn't work with virtual member function

I'm trying to get a class run a thread, which will call a virtual member function named Tick() in a loop. Then I tried to derive a class and override the base::Tick().
but when execute, the program just call the base class's Tick instead of override one. any solutions?
#include <iostream>
#include <atomic>
#include <thread>
#include <chrono>
using namespace std;
class Runnable {
public:
Runnable() : running_(ATOMIC_VAR_INIT(false)) {
}
~Runnable() {
if (running_)
thread_.join();
}
void Stop() {
if (std::atomic_exchange(&running_, false))
thread_.join();
}
void Start() {
if (!std::atomic_exchange(&running_, true)) {
thread_ = std::thread(&Runnable::Thread, this);
}
}
virtual void Tick() {
cout << "parent" << endl;
};
std::atomic<bool> running_;
private:
std::thread thread_;
static void Thread(Runnable *self) {
while(self->running_) {
self->Tick();
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
};
class Fn : public Runnable {
public:
void Tick() {
cout << "children" << endl;
}
};
int main (int argc, char const* argv[])
{
Fn fn;
fn.Start();
return 0;
}
outputs:
parent
You can't let an object run out of scope until you're finished using it! The return 0; at the end of main causes fn to go out of scope. So by the time you get around to calling tick, there's no guarantee the object even exists any more.
(The logic in ~Runnable is totally broken. Inside the destructor is way too late -- the object is already at least partially destroyed.)
The approach of using inheritance with the parent serving as control for the thread and the children implementing the functions is a bad idea in general. The common problems with this approach come from construction and destruction:
if the thread is started from the constructor in the parent (control) then it might start running before the constructor completes and the thread might call the virtual function before the complete object has been fully constructed
if the thread is stopped in the destructor of the parent, then by the time that the control joins the thread, the thread is executing a method on an object that does no longer exist.
In your particular case you are hitting the second case. The program starts executing, and in main the second thread is started. At that point there is a race between the main thread and the newly launched, if the new thread is faster (unlikely, as starting the thread is an expensive operation), it will call the member method Tick that will be dispatched to the final overrider Fn::Tick.
But if the main thread is faster it will exit the scope of main, and it will start destruction of the object, it will complete destruction of the Fn object and during construction of the Runnable it will join the thread. If the main thread is fast enough, it will make it to the join before the second thread and wait there for the second thread to call Tick on the now final overrider that is Runnable::Tick. Note that this is Undefined Behavior, and not guaranteed, since the second thread is accessing an object that is being destroyed.
Also, there are other possible orderings, like for example, the second thread could dispatch to Fn::Tick before the main thread starts destruction, but might not complete the function before the main thread destroys the Fn sub object, in which case your second thread would be calling a member function on a dead object.
You should rather follow the approach in the C++ standard: separate the control from the logic, fully construct the object that will be run and pass it to the thread during construction. Note that this is the case of Java's Runnable, which is recommended over extending the Thread class. Note that from a design point of view this separation makes sense: the thread object manages the execution, and the runnable is the code to execute.
A thread is not a ticker, but rather what controls the execution of the ticker. And in your code Runnable is not something that can be run, but rather something that runs other objects that happen to derive from it.

Implement a multithreading environment

I want to implement a multithreading environment using Qt4. The idea is as follows in c++-alike pseudo-code:
class Thread : public QThread {
QList<SubThread*> threads_;
public:
void run() {
foreach(SubThread* thread : threads) {
thread.start();
}
foreach(SubThread* thread : threads) {
thread.wait();
}
}
void abort() {
foreach(SubThread* thread : threads) {
thread.cancel();
}
}
public slots:
// This method is called from the main-thread
// (sometimes via some signal-slot-connection)
void changeSomeSettings() {
abort();
// change settings
start();
}
}
class SubThread : public QThread {
bool isCancelled_;
public:
void run() {
while(!isCancelled or task completed) {
// something that takes some time...
}
}
void cancel() {
if(isRunning() {
isCancelled_ = true;
}
}
}
The purpose is that the slot changeSomeSettings() kills all running threads, commits its changes and restarts it. What I want to achieve is that once this method has been started, it calls "abort" and then waits until all threads have terminated. Using mutexes in a wrong way:
void Thread::changeSomeSettings() {
mutex1.lock();
abort();
mutex2.lock();
start();
mutex1.unlock();
}
void Thread::run() {
foreach(Thread* thread : threads) {
thread.start();
}
foreach(Thread* thread : threads) {
thread.wait();
}
mutex2.unlock();
}
This actually works in Qt under MacOSX, yet according to the documentation mutex2 must be unlocked in the same thread (and in Windows I get an error). What is the best way to achieve my goal without running into racing conditions and deadlocks? Is there a better design than the one I have proposed here?
You probably want to use a condition variable instead of a mutex for this situation. A condition variable is a way for one thread to signal another. QT's implementation appears to be the QTWaitCondition:
I might have the child thread's periodically check the state of the condition variable. This can be done with QTWaitCondition::wait() with a short/0 timeout. If it is being signaled, then lock a shared memory area containing updated data and access the data that needs to be updated. Then that thread can safely restart itself accordingly.
It's usually not a good idea to just abort a thread. You may end up leaking memory/resources/handles/locks/etc. You don't know where that thread is in it's call stack, and there may be no guarantees that the stack will be "unwound" for you and all destructors are called. This is another reason for the child threads checking a condition variable periodically for updated data and having them restart themselves safely with the new data.

A way to destroy "thread" class

Here is a skeleton of my thread class:
class MyThread {
public:
virutal ~MyThread();
// will start thread with svc() as thread entry point
void start() = 0;
// derive class will specialize what the thread should do
virtual void svc() = 0;
};
Somewhere in code I create an instance of MyThread and later I want to destroy it.
In this case MyThread~MyThread() is called. MyThread:svc() is still running and using the object's data members. So I need a way politely inform MyThread:svc() to stop spinning, before proceeding with the destructor.
What is the acceptable way to destroy the thread object?
Note: I'm looking for platform agnostic solution.
UPD: It's clear that the root of problem is that there's no relationship between C++ object representing thread and OS thread. So the question is: in context of object destuction, is there an acceptable way to make thread object behave like an ordinary C++ object or should it be treated as an unusual one (e.g. should we call join() before destoying it?
Considering your additional requirements posted as comment to Checkers' reply (which is the
most straightforward way to do that):
I agree that join in DTor is problematic for various reasons. But from that the lifetime of your thread object is unrelated to the lifetime of the OS thread object.
First, you need to separate the data the thread uses from the thread object itself. They are distinct entities with distinct lifetime requirements.
One approach is to make the data refcounted, and have any thread that wants to access it hold a strong reference to the data. This way, no thread will suddenly grab into the void, but the data will be destroyed as soon as noone touches it anymore.
Second, about the thread object being destroyed when the thread joins:
I am not sure if this is a good idea. The thread object is normally a way to query the state of a thread - but with a thread object that dies as soon as the thread finishes, noone can tell you wether the thread finished.
Generally, I'd completely decouple the lifetime of the thread object from the lifetime of the OS thread: Destroying your thread object should not affect the thread itself. I see two basic approaches to this:
Thread Handle Object - reference counted again, returned by thread creator, can be released as early as one likes without affecting the OS thread. It would expose methods such as Join, IsFinished, and can give access to the thread shared data.
(If the thread object holds relevant execution state, the threafFunc itself could hold a reference to it, thereby ensuring the instance won't be released before the thread ends)
Thin Wrapper - You simply create a temporary around an OS thread handle. You could not hold additional state for the thread easily, but it might be just enough to make it work: At any place, you can turn an OS thread handle into an thread object. The majority of communication - e.g. telling the thread to terminate - would be via the shared data.
For your code example, this means: separate the start() from the svc()
You'd roughly work with this API (XxxxPtr could be e.g. boost::shared_ptr):
class Thread
{
public:
bool IsFinished();
void Join();
bool TryJoin(long timeout);
WorkerPtr GetWorker();
static ThreadPtr Start(WorkerPtr worker); // creates the thread
};
class Worker
{
private:
virtual void Svc() = 0;
friend class Thread; // so thread can run Svc()
}
Worker could contain a ThreadPtr itself, giving you a guarantee that the thread object exists during execution of Svc(). If multiple threads are allowed to work on the same data, this would have to be a thread list. Otherwise, Thread::Start would have to reject Workers that are already associated with a thread.
Motivation: What to do with rogue threads that block?
Assuming a thread fails to terminate within time for one reason or another, even though you told it to. You simply have three choices:
Deadlock, your applicaiton hangs. That usually happens if you join in the destructor.
Violently terminate the thread. That's potentially a violent termination of the app.
Let the thread run to completion on it's own data - you can notify the user, who can safely save & exit. Or you simply let the rogue thread dance on it's own copy of the data (not reference by the main thread anymore) until it completes.
Usually any OS-specific threads API will allow you to "join" a thread. That is, to block indefinitely on a thread handle until the thread functions returns.
So,
Signal the thread function to return (e.g. by setting a flag in its loop to false).
Join the thread, to make sure the actual thread terminates before you try to delete the thread object.
Then you can proceed with destruction of the thread object (you may also join in the destructor, though some people object to blocking destructors.).
I've had a project before with a similar "thread worker" class and a corresponding "work item" class (a-la Java's Thread and Runnable, except thread does not terminate but waits for a new Runnable object to be executed).
In the end, there was no difference if you join in a separate "shutdown" function or in the destructor, except a separate function is a bit more clear.
If you join in a destructor and a thread blocks, you will wait indefinitely.
If you join in a separate function and a thread blocks, you will wait indefinitely.
If you detach the thread and let it finish on its own, it will usually block application from exiting, so you will wait indefinitely.
So there is no straightforward way to make a thread behave like a regular C++ object and ignore its OS thread semantics, unless you can guarantee that your thread code can terminate almost immediately when notified to do so.
You could havee somthing like this in your svc method
while (alive){ //loops}
//free resources after while.
In your destructor, you could set the alive member to false. Or, you could have a pleaseDie() method, that sets the alive member to false, and can be called from the outside requesting the Thread instance to stop processing.
void
Thread::pleaseDie()
{
this->alive = false;
}
You first need a way to communicate with the thread to tell it to shut down. The best mechanism to do this depends on what svc() is doing. If, for example, it is looping on a message queue, you could insert a "please stop" message in that queue. Otherwise, you could simply add a member bool variable (and synchronize access to it) that is periodically checked by the svc(), and set by the thread wanting to destroy the object. Your could add a pure virtual stop() function to your base class, giving the implementor a clear signal that it has to implement svc() to make its class "runnable", and to implement stop() to make it "stoppable".
After asking the thread to stop, you must wait for it to exit before destroying the object. Again, there are several ways to do this. One is to make the stop() function blocking. It could wait, for example, for a "ok, I'm really stopped now" condition variable to be set by the thread running svc(). Alternatively, the caller could "wait" on the thread running svc(). The way to "wait" is platform dependent.
Most thread systems allow you to send a signal to a thead.
Example: pthreads
pthread_kill(pthread_t thread, int sig);
This will send a signall to a thread.
You can use this to kill the thread. Though this can leave a few of the resources hanging in an undefined state.
A solution to the resource problem is to install a signall handler.
So that when the signal handler is called it throws an exception. This will cause the thread stack to unwind to the entry point where you can then get the thread to check a variable about weather it is sill alive.
NOTE: You should never allow an exception to propogate out of a thread (this is so undefined my eyes bleed thinking about it). Basically catch the exception at the thread entry point then check some state variable to see if the thread should really exit.
Meanwhile the thread that sends the signal should wait for the thread to die by doing a join.
The only issues are that when you throw out of signal handler function you need to be careful. You should not use a signal that is asynchronus (ie one that could have been generated by a signal in another thread). A good one to use is SIGSEGV. If this happens normally then you have accessed invalid memory any you thread should think about exiting anyway!
You may also need to specify an extra flag on some systems to cope.
See This article
A working example using pthreads:
#include <pthread.h>
#include <iostream>
extern "C" void* startThread(void*);
extern "C" void shouldIexit(int sig);
class Thread
{
public:
Thread();
virtual ~Thread();
private:
friend void* startThread(void*);
void start();
virtual void run() = 0;
bool running;
pthread_t thread;
};
// I have seen a lot of implementations use a static class method to do this.
// DON'T. It is not portable. This is because the C++ ABI is not defined.
//
// It currently works on several compilers but will break if these compilers
// change the ABI they use. To gurantee this to work you should use a
// function that is declared as extern "C" this guarantees that the ABI is
// correct for the callback. (Note this is true for all C callback functions)
void* startThread(void* data)
{
Thread* thread = reinterpret_cast<Thread*>(data);
thread->start();
}
void shouldIexit(int sig)
{
// You should not use std::cout in signal handler.
// This is for Demo purposes only.
std::cout << "Signal" << std::endl;
signal(sig,shouldIexit);
// The default handler would kill the thread.
// But by returning you can continue your code where you left off.
// Or by throwing you can cause the stack to unwind (if the exception is caught).
// If you do not catch the exception it is implementation defined weather the
// stack is unwound.
throw int(3); // use int for simplicity in demo
}
Thread::Thread()
:running(true)
{
// Note starting the thread in the constructor means that the thread may
// start before the derived classes constructor finishes. This may potentially
// be a problem. It is started here to make the code succinct and the derived
// class used has no constructor so it does not matter.
if (pthread_create(&thread,NULL,startThread,this) != 0)
{
throw int(5); // use int for simplicity in demo.
}
}
Thread::~Thread()
{
void* ignore;
running = false;
pthread_kill(thread,SIGSEGV); // Tell thread it may want to exit.
pthread_join(thread,&ignore); // Wait for it to finish.
// Do NOT leave before thread has exited.
std::cout << "Thread Object Destroyed" << std::endl;
}
void Thread::start()
{
while(running)
{
try
{
this->run();
}
catch(...)
{}
}
std::cout << "Thread exiting" << std::endl;
}
class MyTestThread:public Thread
{
public:
virtual void run()
{
// Unless the signal causes an exception
// this loop will never exit.
while(true)
{
sleep(5);
}
}
};
struct Info
{
Info() {std::cout << "Info" << std::endl;}
~Info() {std::cout << "Done: The thread Should have exited before this" << std::endl;}
};
int main()
{
signal(SIGSEGV,shouldIexit);
Info info;
MyTestThread test;
sleep(4);
std::cout << "Exiting About to Exit" << std::endl;
}
> ./a.exe
Info
Exiting About to Exit
Signal
Thread exiting
Thread Object Destroyed
Done: The thread Should have exited before this
>
You should add dedicated thread management class (i.e. MyThreadMngr), that handles this and other tasks, like book keeping, owning the thread handles etc. The Thread itself should somehow signal to the thread manager that its going to terminate and MyThreadMngr should i.e. have a loop like Tom proposed.
There will probably be more actions that suite into such a thread manager class.
I reckon the easiest way to do this is to wrap the thread execution code in a loop
while(isRunning())
{
... thread implementation ...
}
You can also stop your thread by doing specific calls, for instance when you're using a WIN32 thread you can call TerminateThread on the thread handle in the destructor.
i give a simple and clean design, no signal, no sync, no kill needed.
per your MyThread, i suggest renaming and adding as below:
class MyThread {
public:
virutal ~MyThread();
// will be called when starting a thread,
// could do some initial operations
virtual bool OnStart() = 0;
// will be called when stopping a thread, say calling join().
virtual bool OnStop() = 0;
// derive class will specialize what the thread should do,
// say the thread loop such as
// while (bRunning) {
// do the job.
// }
virtual int OnRun() = 0;
};
the thread interface user will control the lifetime of MyThread.
and actually the real thread object is as below:
class IThread
{
public:
virtual API ~IThread() {}
/* The real destructor. */
virtual void Destroy(void) = 0;
/* Starts this thread, it will call MyThread::OnStart()
* and then call MyThread::OnRun() just after created
* the thread. */
virtual bool Start(void) = 0;
/* Stops a thread. will call MyThread::OnStop(). */
virtual void Stop(void) = 0;
/* If Wait() called, thread won't call MyThread::OnStop().
* If could, it returns the value of MyThread::OnRun()
* returned */
virtual int Wait(void) = 0;
/* your staff */
virtual MyThread * Command(void) = 0;
};
/* The interface to create a thread */
extern IThread * ThrdCreate(MyThread *p);
See the complete interfaces
http://effoaddon.googlecode.com/svn/trunk/devel/effo/codebase/addons/thrd/include/thrd_i.h
Coding Examples
Case 1. Controlled thread loop
class ThreadLoop : public MyThread
{
private:
bool m_bRunning;
public:
virtual bool OnStart() { m_bRunning = true; }
virtual bool OnStop() { m_bRunning = false; }
virtual int OnRun()
{
while (m_bRunning) {
do your job;
}
}
};
int main(int argc, char **argv)
{
ThreadLoop oLoop;
IThread *pThread = ThrdCreate(&oLoop);
// Start the thread, it will call Loop::OnStart()
//and then call Loop::OnRun() internally.
pThread->Start();
do your things here. when it is time to stop the thread, call stop().
// Stop the thread, it will call Loop::OnStop(),
// so Loop::OnRun() will go to the end
pThread->Stop();
// done, destroy the thread
pThread->Destroy();
}
Case 2. Don't know when the thread will stop
class ThreadLoop : public MyThread
{
public:
virtual bool OnStart() { }
virtual bool OnStop() { }
virtual int OnRun()
{
do your job until finish.
}
};
int main(int argc, char **argv)
{
ThreadLoop oLoop;
IThread *pThread = ThrdCreate(&oLoop);
// Start the thread, it will call Loop::OnStart()
//and then call Loop::OnRun() internally.
pThread->Start();
do your things here. Since you don't know when the job will
finish in the thread loop. call wait().
// Wait the thread, it doesn't call Loop::OnStop()
pThread->Wait();
// done, destroy the thread
pThread->Destroy();
}
A complete IThread implementation:
see
http://effoaddon.googlecode.com/svn/trunk/devel/effo/codebase/addons/thrd/src/thrd/thrd.cpp