(p)threads : safe code?

Started by
4 comments, last by aboeing 17 years, 5 months ago
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!!
Advertisement
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.
AFAIK, your program would work and indeed is guaranteed to print 0, 1, 2, 3 and 4, but not necessarily in that order.
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.
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.
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.

This topic is closed to new replies.

Advertisement