Waiting for a thread.. (pthread_join with timeout)


E-mail this post



Remember me (?)



All personal information that you provide here will be governed by the Privacy Policy of Blogger.com. More...



I recently found myself needing a way to wait for a thread to complete without blocking indefinitely in the case that the waitee runs indefinitely. So i thought, hey I'll just call wait_with_timeout (or whatever pthreads calls it), and I'll be set. In win32 they have this, it's implemented via the ubiquitous WaitForSingleObject(), and you just pass the thread handle and a timeout.

Well, the only problem is that pthreads just doesn't have this api. Only thing (that I can find), is pthread_join(). This will however, block the calling thread until the waitee finishes, or the calling thread is pthread_cancel()ed. So I started thinking about what I can do to implement something like the WaitForSingleObject() behavior, and this is what I came up with:


#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/select.h>

#define PTHREAD_JOIN_POLL_INTERVAL 10
#define false 0
#define true (!false)

typedef struct _waitData waitData;

struct _waitData
{
pthread_t waitID;
pthread_t helpID;
int done;
};

void
sleep_msecs(int msecs)
{
struct timeval tv;

tv.tv_sec = msecs/1000;
tv.tv_usec = (msecs % 1000) * 1000;
select (0,NULL,NULL,NULL,&tv);
}
unsigned int
get_ticks()
{
struct timeval tv;

gettimeofday(&tv, NULL);
return (tv.tv_usec/1000 + tv.tv_sec * 1000);
}

void *
join_timeout_helper(void *arg)
{
waitData *data = (waitData*)arg;

pthread_join(data->waitID, NULL);
data->done = true;
return (void *)0;
}

int
pthread_join_timeout(pthread_t wid, int msecs)
{
pthread_t id;
waitData data;
unsigned int start = get_ticks();
int timedOut = false;

data.waitID = wid;
data.done = false;

if (pthread_create(&id, NULL, join_timeout_helper, &data) != 0)
return (-1);
do {
if (data.done)
break;
/* you could also yield to your message loop here... */
sleep_msecs(PTHREAD_JOIN_POLL_INTERVAL);
} while ((get_ticks() - start) < msecs);
if (!data.done)
{
pthread_cancel(id);
timedOut = true;
}
/* free helper thread resources */
pthread_join(id, NULL);
return (timedOut);
}


It seems like a lot of effort for what I'm getting in return, but it seems to work pretty well. I'm a little bit concerned about the overhead of spinning off a new thread to handle this, but at least on Linux this is (fairly) cheap. The code runs on OS X without modification as well.


0 Responses to “Waiting for a thread.. (pthread_join with timeout)”

Leave a Reply

      Convert to boldConvert to italicConvert to link

 


About me

Previous posts

Archives

Links


    ATOM 0.3