Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Jul 13th, 2007, 6:18 AM   #1
rwm
Professional Programmer
 
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2 rwm is on a distinguished road
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!

rwm is offline   Reply With Quote
Old Jul 13th, 2007, 6:45 AM   #2
The Dark
Expert Programmer
 
Join Date: Jun 2005
Posts: 852
Rep Power: 4 The Dark is on a distinguished road
You need to pass a start_routine to pthread_create. Otherwise, the new thread won't know what to do.
The Dark is offline   Reply With Quote
Old Jul 13th, 2007, 6:57 AM   #3
rwm
Professional Programmer
 
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2 rwm is on a distinguished road
hey man! thanks for the reply!

ah thats why!

thanks for pointing that out
rwm is offline   Reply With Quote
Old Jul 16th, 2007, 4:31 AM   #4
rwm
Professional Programmer
 
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2 rwm is on a distinguished road
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!

rwm is offline   Reply With Quote
Old Jul 16th, 2007, 7:37 AM   #5
The Dark
Expert Programmer
 
Join Date: Jun 2005
Posts: 852
Rep Power: 4 The Dark is on a distinguished road
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.
The Dark is offline   Reply With Quote
Old Jul 16th, 2007, 8:30 AM   #6
rwm
Professional Programmer
 
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2 rwm is on a distinguished road
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!
rwm is offline   Reply With Quote
Old Jul 16th, 2007, 8:44 PM   #7
The Dark
Expert Programmer
 
Join Date: Jun 2005
Posts: 852
Rep Power: 4 The Dark is on a distinguished road
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.
The Dark is offline   Reply With Quote
Old Jul 17th, 2007, 12:07 AM   #8
lectricpharaoh
Caffeinated Neural Net
 
lectricpharaoh's Avatar
 
Join Date: Jun 2005
Location: Dry west coast of Canada
Posts: 1,038
Rep Power: 5 lectricpharaoh will become famous soon enough
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
lectricpharaoh is offline   Reply With Quote
Old Jul 17th, 2007, 2:44 AM   #9
rwm
Professional Programmer
 
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2 rwm is on a distinguished road
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!
rwm is offline   Reply With Quote
Old Jul 17th, 2007, 9:59 AM   #10
rwm
Professional Programmer
 
Join Date: Jan 2007
Location: Cape Town
Posts: 291
Rep Power: 2 rwm is on a distinguished road
hey dont worry guys, ive fixed it!

thanks for the help!
rwm is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

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




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 11:43 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC