Sign in to follow this  
aboeing

(p)threads : safe code?

Recommended Posts

Hi, I was wondering, looking at the code below, does it contain a problem with the 't' variable or not? (due to thread timing, or does it get copied) ie: Is there a problem, in that starting a thread takes an undetermined ammount of time, such that the PrintHello function would not necesarlly print 1->5, but instead might print 13345 (assuming the second thread is delayed in reading the 't') OR Depending on the calling convention, (ie : assuming no __fastcall), since the parameters are copied (ie: t is copied onto the stack anyway) - this program will always work correctly (ie: it will always print 12345 (well, not neccesarily in that order, but always 5,4,3,2 and 1 - never eg:13345)) Basically: What EXACTLY happens to the stack when a new thread is created?
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
printf("\n%d: Hello World!\n", (int) threadid);
pthread_exit(NULL);
return 0;
}
int main (int argc, char *argv[])
{ pthread_t threads[NUM_THREADS];
int rc, t;
for(t=0;t < NUM_THREADS;t++){
printf("Creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
}
}
getchar();
pthread_exit(NULL);
return 0;
}
(see a similar incorrect example here :http://www.llnl.gov/computing/tutorials/pthreads/, but it is different since it passes a pointer to t) Thanks!!

Share this post


Link to post
Share on other sites
No, printf() is not thread safe. It's possible to end up with one thread jumping in and printing some or all of it's message while another one is still printing, giving output like:

0: Hel1: Hello World!
lo World!


EDIT: I think I mis-understood the question...
The thread is passed the value of t at the time pthread_create() was called. So the threads will always have the correct values passed to them.
When you create a thread, a new stack and context is created for it, and then any parameters are pushed onto that stack, before the function that creates the thread returns. All that happens in the context of the main thread, so there won't be any syncronisation issues until your app enters the thread entry point.

Share this post


Link to post
Share on other sites
AFAIK, your program would work and indeed is guaranteed to print 0, 1, 2, 3 and 4, but not necessarily in that order.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Couple of points.
PrintHello should use a synchronisation method.
After using C++ for such a long time, I look at this and think "I like type safety", I don't ever remember C allowing bad casts like those on t. You want to pass the address of t to create and in print cast to int* and dereference.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Sorry the second point is not correct and will cause problems, instead pass a dynamic copy of t. It you pass the address of t it be changed by the main thread.

Share this post


Link to post
Share on other sites
Thanks for the replies, yes I'm aware that printf isn't thread safe and the casts aren't pretty.

Thanks for the stack explanation Evil Steve! I understand what happens now :) Cheers.

Share this post


Link to post
Share on other sites

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