![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Professional Programmer
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2
![]() |
portable thread implementation problem
Heya!
Im trying to create a portable thread library, as you can see this is just a test with POSIX threads... Im confused as to why this is causing a seg fault... #include <iostream>
using namespace std;
//POSIX threads
#include <pthread.h>
#include <semaphore.h>
class test {
public:
test() {
::pthread_create(&_thread,0,0,0);
}
~test() {
::pthread_join(_thread,0);
}
void run() {
cout << "running thread" << endl;
}
private:
//invalidate copy operations
test(const test &); //no impl
test &operator=(const test &); //no impl
//data
pthread_t _thread;
};
int main() {
test _test;
_test.run();
//test::~test() causes seg fault
return 0;
}hope someone can help! thanks! ![]() |
|
|
|
|
|
#2 |
|
Expert Programmer
Join Date: Jun 2005
Posts: 852
Rep Power: 4
![]() |
You need to pass a start_routine to pthread_create. Otherwise, the new thread won't know what to do.
|
|
|
|
|
|
#3 |
|
Professional Programmer
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2
![]() |
hey man! thanks for the reply!
ah thats why! thanks for pointing that out ![]() |
|
|
|
|
|
#4 |
|
Professional Programmer
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2
![]() |
heya!
i spent the whole weekend studying open source software - looking for a way to write a portable thread class. ive written a simple Thread class and well im having a problem understanding why this code is running like so: #include <iostream>
using namespace std;
class Exception : public std::exception {
...
};
//-------------------------------------------------------------------//
class Thread {
public:
//constructor
Thread();
//destructor
virtual ~Thread();
//run thread
void run();
private:
//prevent copy construction
//we dont explicitly create
//a new copy, just return "this"
Thread(const Thread &other) {
*this = other;
}
Thread &operator=(const Thread &) {
return *this;
}
//start thread
void start();
//thread function
static void *threadFunction(void *arg);
//data
pthread_t thread;
protected:
//threads execution task
virtual void execute() = 0;
};
//-------------------------------------------------------------------//
Thread::Thread() {
start();
}
Thread::~Thread() {
if(pthread_join(thread,0) != 0)
throw Exception("could not join thread",__FILE__,__LINE__);
}
void Thread::run() {
execute();
}
void Thread::start() {
if(pthread_create(&thread,0,&(Thread::threadFunction),this) != 0)
throw Exception("could not create new thread",__FILE__,__LINE__);
}
void *Thread::threadFunction(void *arg) {
Thread *thd = reinterpret_cast<Thread *>(arg);
if(thd)
thd->run();
return (void *)0;
}
//-------------------------------------------------------------------//
class TestThread : public Thread {
public:
TestThread() : Thread() {}
~TestThread() {}
protected:
void execute() {
cout << "Executing Test thread..." << endl;
for(int i=0; i<5; i++) {
cout << "Test thread working..." << endl;
sleep(1);
}
cout << "Test thread terminating..." << endl;
}
};
//-------------------------------------------------------------------//
int main() {
//
try {
//
TestThread tt;
tt.run();
} catch(Exception x) {
cout << x << endl;
}
return 0;
}this is the output Executing Test thread... Test thread working... Executing Test thread... Test thread working... Test thread working... Test thread working... Test thread working... Test thread working... Test thread working... Test thread working... Test thread working... Test thread working... Test thread terminating... Test thread terminating... i dont understand why the thread is being executed twice??? hope someone can help! thanks! ![]() |
|
|
|
|
|
#5 |
|
Expert Programmer
Join Date: Jun 2005
Posts: 852
Rep Power: 4
![]() |
Your thread is being run through the threadFunction, but you are also calling run() again in the main(). Take out the tt.run(); call in your main().
I'd recommend that you change the way your thread class works so that it doesn't autostart. Otherwise you cant create a few different threads objects and control when they start. |
|
|
|
|
|
#6 |
|
Professional Programmer
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2
![]() |
heya!
thanks for the reply! ok, i already tried that, didnt work, i guess this is what you meant? ive changed it, so the thread doesnt autostart - all i have to do is call the start() method and the thread will begin executing: #include <iostream>
using namespace std;
class Exception : public std::exception {
public:
Exception() {}
Exception(std::string s) : str(s) {}
virtual ~Exception() throw() {}
friend ostream &operator<<(ostream &stream,const Exception &src) {
return stream << src.str << endl;
}
private:
std::string str;
};
//-------------------------------------------------------------------//
class Thread {
public:
Thread() {}
virtual ~Thread();
void start();
private:
static void *threadFunction(void *arg);
pthread_t thread;
protected:
virtual void run() = 0;
};
//-------------------------------------------------------------------//
Thread::~Thread() {
if(pthread_join(thread,0) != 0)
throw Exception("could not join thread");
}
void Thread::start() {
if(pthread_create(&thread,0,&(Thread::threadFunction),this) != 0)
throw Exception("could not create new thread");
}
void *Thread::threadFunction(void *arg) {
Thread *thd = reinterpret_cast<Thread *>(arg);
if(thd)
thd->run();
return (void *)0;
}
//-------------------------------------------------------------------//
class TestThread : public Thread {
public:
TestThread() : Thread() {}
~TestThread() {}
protected:
void run() {
cout << "Running Test thread..." << endl;
for(int i=0; i<5; i++) {
cout << "Test thread working..." << endl;
sleep(1);
}
cout << "Test thread terminating..." << endl;
}
};
//-------------------------------------------------------------------//
int main() {
//
try {
//
TestThread tt;
tt.start();
} catch(Exception x) {
cout << x << endl;
}
return 0;
}i get this: pure virtual method called terminate called without an active exception Aborted (core dumped) hope you can help! thanks! ![]() |
|
|
|
|
|
#7 |
|
Expert Programmer
Join Date: Jun 2005
Posts: 852
Rep Power: 4
![]() |
The problem is that your tt variable is going out of scope before the thread has time to work. Even though you have the pthread_join in the destructor of Thread, I think by that by the time the inner destructor is called, the virtual function pointers have been removed.
You can test this by getting some keyboard input after the "start" call. The thread then works. This is probably why your first version worked (twice) the thread had a chance to start before the object went out of scope. Also note that you should initialise "thread" to 0 in the constructor, just in case somebody creates a Thread object but doesn't call start. You could add a "WaitForExit" function and call it in your derived class destructor, but that makes it a bit less convenient to use. I think because threading is run concurrently, it doesn't lend itself well to objects you can create on the stack, as they will get destroyed when they fall out of scope, even if the thread is still running. At work we use a reference counter approach, so that the object is only destroyed once the thread is finished and the calling function has indicated it is finished as well. |
|
|
|
|
|
#8 |
|
Caffeinated Neural Net
![]() Join Date: Jun 2005
Location: Dry west coast of Canada
Posts: 1,038
Rep Power: 5
![]() |
Another approach you could try is to make the constructor(s) private, and have static 'factory methods' to create instances. These instances could create the objects on the heap, so you wouldn't have problems with them being destructed (yes, desctructed) prematurely. You'd still need to make sure you don't lose the reference before the thread gets stopped and the object gets released, or you'll have a memory leak, but there are ways to encapsulate much of this fucntionality as well.
__________________
And once again, Probability proves itself willing to sneak into a back alley and service Drama as would a copper-piece harlot. - Vaarsuvius, Order of the Stick |
|
|
|
|
|
#9 |
|
Professional Programmer
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2
![]() |
hey guys!
thanks for the replies! oh ok, that makes sense! mmm... i guess reference counting could work, but thats a little inconvenient... or i could try adding a conditional in my start() method but again thats a hassle... do you have any links to any tutorials/open source that you reccomend? ive been googling a while and found a couple, but both work the same way (using conditionals) thanks guys! ![]() |
|
|
|
|
|
#10 |
|
Professional Programmer
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2
![]() |
hey dont worry guys, ive fixed it!
thanks for the help! ![]() |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| problem with node implementation | brad sue | C++ | 12 | Mar 4th, 2007 11:27 PM |
| Accessing another thread | BlazingWolf | C# | 2 | Apr 19th, 2006 4:19 PM |
| threads | jayme | C++ | 21 | Jan 28th, 2006 10:20 PM |
| CPU Usage goes to 100% when pthread_cond_wait is being used | zen_buddha | C++ | 1 | Oct 13th, 2005 5:59 AM |
| Passing array as argument to a thread | Symptom | C | 5 | Sep 30th, 2005 6:52 PM |