strange behaviour with threads

Below is a small program in which main() creates two threads. Each thread
simply prints out it’s TID. At the bottom of main are two pthread_joins
which prevent main from exiting before the 2 created threads have had the
opportunity to do their printf’s.

This works fine. The strange behaviour comes about when I try removing the
pthread_joins. This introduces a race condition between the created
threads, and whether they will be able to do their printf’s before the main
exit()'s. Because of this I would suspect that there is the possibilty that
I wouldn’t see the text from the threads printf()'s. What actually happens
is that I see the printf from the second thread twice!!!?!

Anybody have an idea why?

void* thread_A(void* arg)
{
printf(“This is thread A\n”);
printf(“My tid is %d\n”, pthread_self() );
return(NULL);
}

void* thread_B(void* arg)
{
printf(“This is thread B\n”);
printf(“My tid is %d\n”, pthread_self() );
return(NULL);
}

int main(void)
{
pthread_t tid_A, tid_B;

pthread_create(&tid_A, NULL, thread_A, NULL);
pthread_create(&tid_B, NULL, thread_B, NULL);

// pthread_join(tid_A, NULL);
// pthread_join(tid_B, NULL);

exit(EXIT_SUCCESS);
}

/***** OUTPUT ******************

/home/src/threads/rel->./thread2
This is thread A
My tid is 1
This is thread B
This is thread B <------------ “eh ?!?”
My tid is 2

Chris Foran <chrisforan@rogers.com> wrote:

Below is a small program in which main() creates two threads. Each thread
simply prints out it’s TID. At the bottom of main are two pthread_joins
which prevent main from exiting before the 2 created threads have had the
opportunity to do their printf’s.

This works fine. The strange behaviour comes about when I try removing the
pthread_joins. This introduces a race condition between the created
threads, and whether they will be able to do their printf’s before the main
exit()'s. Because of this I would suspect that there is the possibilty that
I wouldn’t see the text from the threads printf()'s. What actually happens
is that I see the printf from the second thread twice!!!?!

Anybody have an idea why?

The correct answer is that it doesn’t matter… You’re allowing your
threads call printf() after the exit() call in the main thread may have
closed stdout, which is undefined behaviour. (Imagine that exit() calls
fclose(), and fclose() frees the memory that stdout points to, and
either free() or something else that exit() calls later overwrites that
memory – if you call printf() then, it may end up writing to a
completely unrelated fd…)

It’s kind of funny that I get the correct ouptut if I change the exit()
call to fclose(stdout). But if I stick fflush(NULL) in front of it, the
duplicated line comes back.


Wojtek Lerch QNX Software Systems Ltd.

Wojtek Lerch <wojtek_l@yahoo.ca> wrote:

Chris Foran <> chrisforan@rogers.com> > wrote:
Below is a small program in which main() creates two threads. Each thread
simply prints out it’s TID. At the bottom of main are two pthread_joins
which prevent main from exiting before the 2 created threads have had the
opportunity to do their printf’s.

This works fine. The strange behaviour comes about when I try removing the
pthread_joins. This introduces a race condition between the created
threads, and whether they will be able to do their printf’s before the main
exit()'s. Because of this I would suspect that there is the possibilty that
I wouldn’t see the text from the threads printf()'s. What actually happens
is that I see the printf from the second thread twice!!!?!

Anybody have an idea why?

The correct answer is that it doesn’t matter… You’re allowing your
threads call printf() after the exit() call in the main thread may have

The correct explanation is that while pthread_create() isn’t a blocking
call, and therefore the threads should simply be put onto the scheduling
queue with no chance to run, exit() most likely is a blocking call – it
sends a message to the process manager telling it to shut down the process.
Therefore, since the main() thread blocks, the two threads now get a chance
to run.

You are correct, however, in implying that this is sloppy and has a race
condition :slight_smile:

closed stdout, which is undefined behaviour. (Imagine that exit() calls
fclose(), and fclose() frees the memory that stdout points to, and
either free() or something else that exit() calls later overwrites that
memory – if you call printf() then, it may end up writing to a
completely unrelated fd…)

It’s kind of funny that I get the correct ouptut if I change the exit()
call to fclose(stdout). But if I stick fflush(NULL) in front of it, the

This is expected; fclose() calls the stdout resmgr and blocks the process,
giving the 2 threads a chance to run. The duplicated output is most likely
as a result of a race condition.

Cheers,
-RK

duplicated line comes back.


Wojtek Lerch QNX Software Systems Ltd.


Robert Krten, PARSE Software Devices +1 613 599 8316.
Realtime Systems Architecture, Books, Video-based and Instructor-led
Training and Consulting at www.parse.com.
Email my initials at parse dot com.

nospam88@parse.com (Robert Krten) wrote in news:ad1j7v$haa$1@inn.qnx.com:


The correct explanation is that while pthread_create() isn’t a
blocking call, and therefore the threads should simply be put onto the
scheduling queue with no chance to run, exit() most likely is a
blocking call – it sends a message to the process manager telling it
to shut down the process. Therefore, since the main() thread blocks,
the two threads now get a chance to run.

Just a slight spin on things - while pthread_create() may/maynot block the
momment you’ve called the create function, you cannot assume the thread
you’ve requested to create isn’t running (I’m speaking in general, you
could assign it a priority to make this a guarantee) or hasn’t run before
you return from the pthread_create() call. While there are ways to enforce
the order of execution, in general, you should be wary.


\

Cheers,
Adam

QNX Software Systems Ltd.
[ amallory@qnx.com ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <pschon@baste.magibox.net>

Adam Mallory <amallory@qnx.com> wrote:

Just a slight spin on things - while pthread_create() may/maynot block the
momment you’ve called the create function, you cannot assume the thread
you’ve requested to create isn’t running (I’m speaking in general, you
could assign it a priority to make this a guarantee) or hasn’t run before
you return from the pthread_create() call. While there are ways to enforce
the order of execution, in general, you should be wary.

Even assigning a priority is not a guarantee unless you also have a
guarantee that your code will never need to work on a multiprocessor.


Wojtek Lerch QNX Software Systems Ltd.