#include <boost/thread.hpp>
#include <iostream>
usingnamespace std;
template <typename T>
class Thread {
private:
boost::thread* thread;
public:
virtualvoid run() = 0;
void start() {
if(thread && thread->isRunning()) {// how to check if the thread is running?
return;
}
thread = new boost::thread(&T::run, (T*)this);
}
//void kill() {
//}
};
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#include "../Thread.h"
// usage:
// a concrete class for test
class test : public Thread<test> {
public:
void run() {
cout << "run" << endl;
}
};
int main() {
test t;
t.start();
return 0;
}
but how to check if a thread has finished or not? I can't find function like isRunning() or hasFinished() from boost::thread.
and another question is: if a thread function is block and takes long, such as:
for(i=0; i<veryLargeNumber; i++) {
// something block and takes very long time
}
how can I stop the thread? thread->interrupt() could kill that?
if(thread && thread->isRunning()) {// how to check if the thread is running?
The typical solution is to allow only one call to start() per instance of Thread by setting a member.
how can I stop the thread? thread->interrupt() could kill that?
It's never a good idea to kill threads. Whenever possible and necessary, have the thread poll a flag and give all blocking I/O operations a timeout.
The Thread class can be implemented without templates, by the way. If you're going to have pure virtual functions, at least take advantage of polymorphism.
There is a thread container made by boost called thread_group which is probably a bit more useful than std::vector (or at least, I use it anyways. I think its just preference.).
Besides that, I'm confused as to what you want to do? If the main objective is just to split the initialization and execution apart, I don't see the point.
haha, it looks better now? I think the Thread class should support start/stop/isRunning/restart , but when I run the test, there is an exception. it seems the "this" pointer is wrong, how to let the "this" point to the derived class?
I'm new to boost, Thanks in advance.
Hi jsmith, this can solve it. but I feel a little uncomfortable to use both template and virtual function in this class :)
since the template is necessary here, is there anyway smart way to convert the "virtual operator()" to a template way?
Thanks.
the two commented lines causes error on compile, I see some tutorial does exactly like this,
boost::thread( boost::bind(&menberFunc, objectReference) )
how can I fix this?
the code compiles but I don't know why... see the comments below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
template<typename T>
class Thread {
public:
void start() {
T* derived = dynamic_cast<T*>(this);
// there are 3 arguments in the boost::bind,
// argument 1(&thread::doIt) and argument 2(this) means binding a member function
// but what's the 3th argument for? doesn't it mean the argument of doIt?
// I removed it and it also compiles
thread = new boost::thread(boost::bind(&Thread::doIt, this, boost::ref(*derived)));
}
// void doIt() { // this compiles
//(*derived)();
// }
// this won't compile, why doesn't the third argument above used here
void doIt(T* derived) {
//(*derived)();
}
};
The line I gave you says to call Thread::doIt on the "this" object with boost::ref( *derived )
as the first parameter to doIt(). boost::ref() is a container that holds a non-const reference,
which is what your original doIt() expected.
In your code below, doIt takes a T*, which is a pointer, not a reference, hence the compile
error. If you want it to take a pointer for some reason, then change boost::ref( *derived )
to just derived.