C++ Errors C2893, C2780, C2672 when using future, promise, detached thread - c++

I have got a class named cApp.
I want to run CheckProcessList() in the background until the program terminates. So i thought, well, lets run it in a detached thread until ~cApp(). I made a bool to break out of the loop in CheckProcessList(). In ~cApp I set the bool true m_bTerminateThread = true to break out and wait for the promise m_barrierFuture->wait() that the thread has ended execution. After breaking out i set the promise barrier.set_value() that the thread is now ending execution. Now ~cApp can finish execution. Or at least that is my understanding of the things i want to achieve and how to do it. Well, can't be right since i get Compiler Errors.
Why did it want to check if the thread finished in the first place? Because the program breaks at runtime when it terminates and the thread is at that moment in GetProcId(). If it is sleeping in the moment of termination the program does not break.
I searched msdn and stackoverflow for answers but i do not get anything out of it that i can understand. I am using VS2019 and C++14. Thank you guys in advance.
cApp.h
#pragma once
#include "wx/wx.h"
#include "cMain.h"
#include <thread>
#include <future>
class cApp
: public wxApp
{
public:
cApp();
~cApp();
virtual bool OnInit();
private:
// supposed to run in a detached thread
// until the program terminates
void CheckProcessList(std::promise<void> barrier);
// Checks whether or not the game processes are running
// this thread runs asynchronous until ~cApp
std::thread* m_tCheckProcList;
// used in thread "m_tCheckProcList"
// if set to true the thread terminates asap
bool m_bTerminateThread;
// used in thread "m_tCheckProcList"
// in ~cApp this future waits for the promise that the thread has finished
std::future<void>* m_barrierFuture;
// Dark Souls 3 Processname
const wchar_t* m_ds3Name;
// Need for Speed: Most Wanted Processname
const wchar_t* m_nfsmwName;
// Serious Sam: The Second Encounter Processname
const wchar_t* m_sstseName;
const wxString* m_frameTitle;
const wxSize* m_frameSize;
cMain* m_mainFrame;
};
cApp.cpp
#include "cApp.h"
wxIMPLEMENT_APP(cApp);
cApp::cApp()
{
m_ds3Name = L"DarkSoulsIII.exe";
m_sstseName = L"SeriousSam.exe";
m_nfsmwName = L"speed.exe";
m_frameTitle = new wxString("DeltaWin");
m_frameSize = new wxSize(600, 450);
m_bTerminateThread = false;
m_mainFrame = nullptr;
m_tCheckProcList = nullptr;
m_barrierFuture = nullptr;
}
cApp::~cApp()
{
// send the thread the "signal" to finish asap
m_bTerminateThread = true;
// wait for thread "m_tCheckProcList" to finish execution
m_barrierFuture->wait();
}
bool cApp::OnInit()
{
// create main top-level window
m_mainFrame = new cMain(*m_frameTitle, wxDefaultPosition, *m_frameSize);
m_mainFrame->Show();
// create barrier and instantiate the future for it
std::promise<void> barrier;
m_barrierFuture = new std::future<void>(barrier.get_future());
// start checking for running game processes in asynchronous thread
m_tCheckProcList = new std::thread(&cApp::CheckProcessList, std::move(barrier));
m_tCheckProcList->detach();
return true;
}
void cApp::CheckProcessList(std::promise<void> barrier)
{
while (!m_bTerminateThread)
{
// Dark Souls 3
if (GetProcId(m_ds3Name) == 0)
m_mainFrame->MenuItemEnable(false, menuItem::DarkSouls3);
else
m_mainFrame->MenuItemEnable(true, menuItem::DarkSouls3);
// Need for Speed: Most Wanted
if (GetProcId(m_nfsmwName) == 0)
m_mainFrame->MenuItemEnable(false, menuItem::NFSMostWanted);
else
m_mainFrame->MenuItemEnable(true, menuItem::NFSMostWanted);
// Serious Sam: The Second Encounter
if (GetProcId(m_sstseName) == 0)
m_mainFrame->MenuItemEnable(false, menuItem::SeriousSamTSE);
else
m_mainFrame->MenuItemEnable(true, menuItem::SeriousSamTSE);
// Sleep 1.5s to save resources
std::this_thread::sleep_for(std::chrono::milliseconds(1500));
}
// set the promise that the thread has ended execution
barrier.set_value();
}
edit:
The program terminates after ~cApp. Therefor i think that in this particular case i do not have to delete all of that memory because the os takes care of it.
edit2:
C2893: Failed to specialize function template
"unknown-type std::invoke(_Callable &&,_Ty1 &&,_Types2 &&...)
noexcept()".
C2780: "unknown-type std::invoke(_Callable &&) noexcept()":
expects 1 arguments - 2 provided
C2672: "invoke": no matching overloaded function found

m_tCheckProcList = new std::thread(&cApp::CheckProcessList, std::move(barrier));
I don't know to which lines your errors pertains (you didn't show this) but I suspect at least above statement is wrong.
If you pass an address of a thread procedure to std::thread constructor and this procedure is a non-static member function the next argument after must be an address of the object you refer to (after all a non-static member function must have an instance that it is called on behalf of). std::promise is not a type which contains such a function pointer type &cApp::CheckProcessList so this cannot work.
If you want to associate that thread with the object that creates it typically such invocation looks like:
std::thread(&cApp::CheckProcessList, this, ...
Or one can use either a static member function or a free function.
cApp::CheckProcessList(std::promise<void> barrier)
Another problem in your code is passing a promise object by value to the thread function. This means a local copy of the promise but promise is not copyable.
You also can't pass it either by reference or by pointer! because barrier is a local variable of OnInit() method and as soon as that method finishes that variable gets destroyed anyway - the underlying detached thread will mess around with invalid stackframe or cause undefined behavior of any kind. Perhaps you could make the barrier a data member or rethink your design.
Be very cautious while dealing with detached threads. They are full of pitfalls when used improperly.

Related

Make something happen after 5 minutes has passed, while other code still runs in C++

I am trying to make a timer, so after five minutes something happens. The catch is that while the timer is being checked constantly I need other code to be running. I have created a sample below, of how the actually code looks, the function with the timer is in class, so I did the same thing below. Here is the code:
This code assumes all necessary headers are included
Class.h:
class MyClass
{
public:
void TimerFunc(int MSeconds);
};
void MyClass::TimerFunc(int MSeconds)
{
Sleep(MSeconds); //Windows.h
//Event code
return;
}
Main.cpp:
int main()
{
MyClass myClass;
myClass.TimerFunc(300); //300 is 5 minutes
//Here we do not want to wait for the five minutes to pass,
//instead we want to continue the rest of the code and check
//for user input as below
std::cout << "This should print before the Event Code happens.";
}
The problem here is that the code waits for the five minutes to pass, and then continues. I'm not sure if threading would be a good option here, I haven't done much with it before, if anyone could help me with that, or knows a better way to go about it, any help is appreciated.
If you don't mind your Event executing in a different thread-context, you could have your Timer class spawn a thread to do the waiting and then the event-execution; or (on POSIX OS's) set up a SIGALRM signal and have the signal handler do the Event. The downside of that is that if your event-code does anything non-trivial, you'll need to worry about race conditions with the concurrently executing main thread.
The other approach is to have your main thread check the clock every so often, and if the time-to-execute has passed, have your main thread call your Event routine at that time. That has the advantage of automatic thread-safety, but the disadvantage is that you'll have to add that code into your thread's main event loop; you can't easily hide it away inside a class like the one in your example.
With C++11 threads, this would work like this:
int main()
{
MyClass myClass;
thread ti([](MyClass &m){m.TimerFunc(300); }, ref(myClass)); // create and launch thread
// ... code executed concurrently to threaded code
ti.join(); // wait for the thread to end (or you'll crash !!)
}
Add a private member to your class:
atomic<bool> run=true; // designed to avoid race issue with concurrent access
Update its timer function to loop while this variable is true:
void MyClass::TimerFunc(int MSeconds)
{
while (run) {
this_thread::sleep_for(chrono::milliseconds(MSeconds)); // standard sleep instead of microsoft's one
//Event code
}
return;
}
Foresee within the class a member function to stop the threaded loop:
void Stop() {
run = false;
}
Finally update main() to call myClass.Stop() when the timer function is no longer needed (i.e. before calling ti.join() )
EDIT: attention, nasty error to avoid: be careful to refer to ref(myClass) in the thread constructor. If you would forget this, the thread ti would use a reference to a copy of myClass instead of the original object.

Waiting for main() to return?

So I have a multithreaded C++ console application in which I want to handle the console close event in order to perform cleanup.
I have something to this effect:
bool running = true;
ServerSocket* server;
std::mutex mutex;
BOOL WINAPI HandlerRoutine(DWORD)
{
running = false;
server->shutdown();
std::lock_guard<std::mutex> guard(mutex);
return TRUE;
}
int main()
{
std::lock_guard<std::mutex> guard(mutex);
SetConsoleCtrlHandler(&HandlerRoutine, TRUE);
try {
ServerSocket server(27015);
::server = &server;
while (running)
{
TCPSocket* client = server.accept(true);
}
}
catch (const ServerSocket::ServerShutdownException&)
{
return 0;
}
}
If I return from HandlerRoutine my program gets terminated unceremoniously, so I have to wait for main() to end.
However, after main ends I get an exception telling me a mutex was destroyed while busy, thrown from dynamic atexit destructor for 'mutex'(). This leads me to believe that static and global variables are destroyed as soon as main returns, leaving my handler function hanging around with invalid globals.
Is this the standard specified behaviour, and if so, any idea about how I can achieve my desired effect?
In this scenario I would simply leak the mutex object. You don't want the destructor called prior to termination of the last thread, and there's no point in calling it during termination of the last thread.
std::mutex& mutex = *new mutex; // freed by OS at process exit
You can try boost::application.
Here the example wait_for_termination_request.cpp
Yes, your deduction is correct. Seems like the best option would be to unregister your handler and then wait for it to finish before returning from main(). But if that's not an option for whatever reason, something else you could do is to wrap all your globals in a struct:
struct Globals
{
bool running;
ServerSocket* server;
std::mutex mutex;
};
Have a single, global shared_ptr to an instance of that struct:
std::shared_ptr<Globals> globals = std::make_shared<Globals>();
Make a copy of the shared_ptr in your handler:
BOOL WINAPI HandlerRoutine(DWORD)
{
std::shared_ptr<Globals> myGlobals = globals;
...
}
And rely exclusively on myGlobals within the handler (there is no guarantee that the globals pointer itself will remain valid for the entire lifetime of the thread). That way everything is kept alive until everyone is done with it.
This assumes, of course, that globals is still valid when HandlerRoutine begins. If that's not the case (i.e. if the system can call the handler after main returns but before the process ends), then I'll delete this answer.
I'd be tempted to play ping pong with mutexes. Have not one, but two mutexes.
The first is held by mymain (a copy of your main basically). main does nothing but call mymain.
The second is held by HandlerRoutine, and aquired by main after returning from mymain.
If you shut down without the HandlerRoutine being called, you simply fall off the end of main.
If you shut down after the HandlerRoutine is called, your main blocks on it finishing.
Simply planning to leak the mutex is insufficient, as if HandlerRoutine is called during the period that main was already planing to shutdown, its server->shutdown could be accessing invalid memory.
Some work on the second mutax (that HandlerRoutine accesses) needs to be done to deal with race conditions (being called -- or reaching the lock -- after main has already exited, and the process is cleaning up global variables?). Storing the HandlerRoutine mutex in a pointer, and using lock-free techniques to access it extremely carefully, possibly involving spin locks.
To expand on the comments mentioning that the mutex is unnecessary, this is one alternative:
BOOL WINAPI HandlerRoutine(DWORD)
{
running = false;
server->shutdown();
Sleep(INFINITE);
return TRUE; // just to stop the compiler complaining
}

How to make asynchronous initializing correctly in Qt?

I have the task of initialisation of an object, that is quite long. What is the right way to go about it?
here is the code i have so far (for simplicity, initialisation consists of adding entries to string list only):
#ifndef TASKINITIALIZER_H
#define TASKINITIALIZER_H
#include <QDir>
#include <QThread>
#include <QObject>
#include "task.h"
class TaskInitializer:public QThread
{
Q_OBJECT
QDir dir;
QString msg;
Task &result;
public:
TaskInitializer(QString dname, bool png, bool jpg, bool bmp, Task &res);
~TaskInitializer();
const QString& getMessage();
bool isOk();
private:
void run();
};
#endif // TASKINITIALIZER_H
#include <QDir>
#include <QDirIterator>
#include "taskinitializer.h"
TaskInitializer::TaskInitializer(QString dname, bool png, bool jpg, bool bmp, Task & res):
dir(dname),result(res)
{
QStringList filters;
if (png)
filters << "*.png";
if(jpg)
{
filters << "*.jpeg" << "*.jpg";
}
if(bmp)
filters << "*.bmp";
dir.setNameFilters(filters);
}
TaskInitializer::~TaskInitializer()
{
}
const QString &TaskInitializer::getMessage()
{
return msg;
}
bool TaskInitializer::isOk()
{
if (!dir.exists())
{
msg = ("Directory does not exist");
return false;
}
if (dir.nameFilters().length() < 1)
{
msg = ("No image types chosen");
return false;
}
return true;
}
void TaskInitializer::run()
{
QDirIterator di(dir,QDirIterator::Subdirectories);
while(di.hasNext())
{
result.addFilename(di.next());
}
}
The ides is to pass parameters to initialiser instance in constructor, check their validity and then run the initialisation itself. However, initialisation may take long and the application may be stopped abruptly; in this case initialiser should stop its activity properly and be cleaned up.
I have read on several methods of running async tasks, but still haven't understood how to detect the stop signal. As far as i can see, running QRunnable in thread pool or using QtConcurrent::run() does not gives any mechanism of checking whether it is time to stop or not.
Also, i am confused of the subject of how to pass the object being initialised properly to and from initialising task, so that it would be guaranteed to be cleaned up. Same with initialiser; how can it be guaranteed to be cleaned up?
here is the code i currently use to launch initialisation:
_temp = new Task();
TaskInitializer *worker = new TaskInitializer(_directoryName,flags[2],flags[1],flags[0],*_temp);
if (!worker->isOk())
{
delete _temp;
_temp = NULL;
emit logMessage(worker->getMessage());
return _temp;
}
//clearTempTask();
emit logMessage("New task created");
connect(worker,SIGNAL(finished()),SIGNAL(taskInitialized()));
connect(worker,SIGNAL(finished()),worker,SLOT(deleteLater()));
worker->start();
worker = NULL;
Well, the quick-and-dirty method would be to have a boolean variable (named pleaseStop or something) that the initializer thread checks every so often to see if the main thread has set it to true or not. If the main thread has set it to true, the thread task would see that and abort its initialization routine and exit.
A slightly nicer method would be to break up the initialization task into smaller parts -- e.g. do 50 milliseconds worth of initialization, then if there is still more initialization left to do, call QTimer::singleShot(0, this, SLOT(DoSomeMore()) and return from the method, such that the DoSomeMore() slot gets called on the next iteration of the Qt event loop, but in the meantime any other pending signals (such as a PleaseQuitNow() type of signal coming in from the main thread, which could be connected to the QThread's quit() slot) would get processed.
In fact, if you keep the time slices short enough, with the second method you may not even need to launch a second thread at all -- the initialization could run in the main thread but GUI events would still get serviced in a relatively timely manner, since they would get interspersed between short DoSomeMore() calls rather than being blocked by a single very lengthy DoEverythingAllInOneGo() call.
As for passing the data object back and forth, simply handing the initializer thread a pointer/reference to the data object is sufficient, as long as you are careful to ensure the following:
The main thread shouldn't read or write the data object until the initializer thread has completed its work
The main thread must guarantee that the data object will remain valid until after the initializer thread has completed its work (e.g. don't delete the data object while the initializer thread might still be using it!)

Start new thread without blocking/waiting of main operation

Maybe there is a really simple solution for my problem, but I'm really confused with all the boosts around me.
Here's my problem:
I want to start a task (calculation, file system operations, etc.), raised by a callback system which calls the CallbackReceived function and I want to pass this operation to a thread, typically represented by a member function of an object. The thread isn't guaranteed to finish, so it should have something to cancel it after some time.
Something like (don't know if this is 100% correct):
// ...
MyObject object;
// ...
void CallbackReceived(int parameter) {
boost::thread tThread(&MyObject::calculate, *&object);
boost::asio::deadline_timer tDeadlineTimer(_ioService, boost::posix_time::seconds(2));
tDeadlineTimer.async_wait(boost::bind(DeadlineTimeOut, boost::asio::placeholders::error));
tThread.join();
}
Basically, a tThread.join()` waits for the return of the thread. While waiting, my main could not receive any callbacks that may come in because it's blocked and sleeps.
So what can one do, to run the thread and not to block the calling initial program while executing the operation?
You can call join just when you need the result of the calculations.
Something like "Future" pattern. Anyway, you would have to make your thread variable global to the CallBackRecieved function (You can write some wrapper).
Note: you can call join, when thread finished its' work - nothing will be blocked.
What do you want to do with the result of calculate?
Your main thread is blocked in the .join().
If you want to handle other callbacks, you have to return to the normal execution flow, waiting for another call.
Then you have to ask yourself what do you do with the result of calculate when it's finished. Maybe the thread can put the result in a shared resource somewhere and finish gracefully.
You must first sort out all what your code is supposed to do ( processing callbacks, starting threads, what to do with the result ) then you can think of implementing it. There are new constructs in boost and C++11 called promise and future that could suit you but first you have to think about what you want.
Actually you could call the callback while your main thread is sleeping. It would just run on the context (stack) of your thread.
You probably don't want to call join at the point you are at but later or never.
Example (pseudocode):
class Worker {
void doWork(void * mainthread){
Main* main = static_cast<Main*>(mainthread);
while(hasWorkTodo){
//work
//inform main
main->callbackwithinformation(information);
}
}
class Main{
atomi_int filesfound;
void main_part(){
//start worker
boost::thread thread(&Worker::doWork, &object, this);
while(hasworktodo){
//do work
//use filesfound here
}
//About to finish make sure we join our thread
thread.join();
}
void callbackwithinformation(int updatedcount){
//here we set a flag or pass some object
//probably will need an atomic operation
filesfound = updatedcount;
}
}
You would define the implementations in cpp and the interface in a h file so no circular dependency would arise, since you are only using Main as a argument in the interface a forward declaration would suffice.
//worker.h
class mainthread;
class Worker {
void doWork(void * mainthread);
}
//worker.cpp
#include "main.h"
void Worker::doWork(/* and so on*/}
//main.h
class Main{
atomi_int filesfound;
void main_part();
void callbackwithinformation(int updatedcount);
}
//main.cpp
//no need for worker.h here
void Main::main_part() /* implementation and so on */

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