Sign in to follow this  

pthread_join

This topic is 4336 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm new to thread programming and I decided to go with posix thread in Win32 using Pthreads-w32 library (http://sourceware.org/pthreads-win32/). Maybe I misunderstood something about the way I should use the library or threading in general but my my simple thread class is not working at all ! This is the code of my thread class so far :
Thread::~Thread (ovoid)
{
	if (state != S_READY)
		pthread_join (thread, onull);
}

ovoid Thread::start (ovoid)
{
	oassert (state == S_READY);
	pthread_attr_init (&attribute);
	pthread_attr_setdetachstate (&attribute, PTHREAD_CREATE_JOINABLE);
	pthread_create (&thread, &attribute, threadFunc, this);
	pthread_attr_destroy (&attribute);
}

ovoid Thread::stop (ovoid)
{
	state = S_STOPPING;
}

void * Thread::threadFunc (void * pParam)
{
	Thread * const pThread = (Thread * const) pParam;
	pThread->state = S_RUNNING;
	pThread->run ();
	pThread->state = S_READY;
	return onull;
}
When I do the following in my main function :
Thread * const pThread = new Thread ();
pThread->start ();
pThread->stop ();
The
pthread_join(...)
from the class destructor never returns... also you may need to know that the
pThread->run
function is empty... There is no loop at all and it still never returns...

Share this post


Link to post
Share on other sites
I haven't used posix but for win32 default threads, you have to create the thread using CreateThread(); in the main function in order to apply the thread to the program. I haven't done any posix though so I wouldn't know if you have created the thread or not..

Share this post


Link to post
Share on other sites
In the destructor u call pthread_join( thread , ..);
this will cause the thread in which the destructor is called untill the
thread identified by "thread"( the first parameter to pthread_join ) terminates.
Thats how pthread_join works. I am not whether u hav got the logic rite in ur program.. post some more code .. may help

Share this post


Link to post
Share on other sites
All the code :

class Thread
{
public:

oinline Thread (ovoid);
virtual ~Thread (ovoid);

ovoid start (ovoid);

virtual ovoid run (ovoid) {};

private:

static void * threadFunc (void * pParam);

pthread_t thread;
};

oinline Thread::Thread (ovoid)
{
}

Thread::~Thread (ovoid)
{
pthread_join (thread, onull); // **** Stall here for eternity****
}

ovoid Thread::start (ovoid)
{
pthread_attr_t attribute;
pthread_attr_init (&attribute);
pthread_attr_setdetachstate (&attribute, PTHREAD_CREATE_JOINABLE);
pthread_create (&thread, &attribute, threadFunc, this);
pthread_attr_destroy (&attribute);
}

void * Thread::threadFunc (void * pParam)
{
// *** Never gets here ! ***
Thread * const pThread = (Thread * const) pParam;
pThread->run ();
return onull;
}

void main (void)
{
Thread * const pThread = new Thread ();
pThread->start ();
delete pThread;
}

Share this post


Link to post
Share on other sites
The class design seems a bit contorted .. my advice remove the
thread func outside the class deifnition

have a member function called

void setTHreadFunction( (void*)(*func_ptr)( void*));

where u pass any function and call the pthread_create from here

This could be made static .

Share this post


Link to post
Share on other sites
Actually, I'm not sure why pthread_join should be running at all. The most likely scenario here is that delete will be called before the newly created thread gets a timeslice, which means I'd expect it to crash when threadFunc tries to access the thread object. More to the point - you need to call pthread_join if the thread is joinable whether it's finished running or not in order to clean up resources, so what you really need is to have two states - one to indicate whether the thread has been started, and a separate one to tell the thread to stop.


Thread::~Thread ()
{
if (started)
pthread_join (thread, NULL);
}

void Thread::start ()
{
assert (!started);
started = true;
pthread_create (&thread, NULL, threadFunc, this);
}

void Thread::stop ()
{
stopping = true;
}

void *Thread::threadFunc (void *pParam)
{
Thread *pThread = reinterpret_cast<Thread*>(pParam);
pThread->run ();
return NULL;
}



By the way, what's all this ovoid and onull business? In C++ you don't need to explicitly state a function has no parameters. I've also removed the thread attributes since they are the default and therefore unnecessary.

The problem with the code above is I don't think it does what you want - the thread can't be restarted again afterwards. If that is a requirement you are going to have to either have some way to indicate a stopped state so you can pthread_join the old thread when it's (almost) finished, just join and wait when the restart is required.

Share this post


Link to post
Share on other sites
Ok this is getting weird, starting to think that it is not my logic that is wrong, The code you saw was embended inside a dll, I copied the same exact code in a simple console project (without dlls) and it work fine... I then told myself that the implementation of pthread on win32 may not like dll environment so I implemented the same code using Win32 threading api (pthread_create = CreateThread, pthread_join = WaitForSingleObject) and I get the same result... WaitForSingleObject stall the program...


class Thread::Implementation
{
public:

oinline Implementation (Thread * const pThread) : pThread (pThread), state (Thread::S_READY)
{
}

oinline ~Implementation ()
{
if (state != S_READY)
WaitForSingleObject (hThread, INFINITE);
}

oinline Thread::State const getState () const
{
return state;
}

oinline ovoid start ()
{
oassert (state == Thread::S_READY);
state = S_RUNNING;
hThread = CreateThread (onull, 0, ThreadProc, pThread, 0, onull);
}

oinline ovoid stop ()
{
if (state == Thread::S_RUNNING)
state = S_STOPPING;
}

static DWORD WINAPI ThreadProc (PVOID pParam)
{
Thread * const pThread = (Thread * const) pParam;
pThread->run ();
pThread->pImplementation->state = S_READY;
return 0;
}

private:

Thread * const pThread;
Thread::State state;
HANDLE hThread;
};


Share this post


Link to post
Share on other sites

This topic is 4336 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this