3

I wrote the following code:

#include <pthread.h>
#include <stdio.h>

void* sayHello (void *x){
    printf ("Hello, this is %d\n", (int)pthread_self());
    return NULL;
}

int main (){
    pthread_t thread;
    pthread_create (&thread, NULL, &sayHello, NULL);
    printf("HERE\n");
    return 0;
}

After compiling and running I saw 3 different types of outputs.

  1. Only "Here" was printed.
  2. "Here" and 1 'sayHello' message.
  3. "Here" and 2 'sayHello' messages.

Of course I'm OK with the second option, but I don't understand why the 'sayHello' massege can be printed 0 or 2 times if I created only one thread?

Asaf Kahlon
  • 104
  • 1
  • 9
  • 1
    I don't know why it would print twice, but unless pThreads work differently, you're not waiting for the thread to join, so there's the possibility that the program will end before `sayHello` is called, which would account for the first case. – Carcigenicate May 21 '15 at 13:40
  • the 'return NULL' in the thread function should be: '' pthread_exit(NULL)' – user3629249 May 22 '15 at 17:48
  • 1) the main() function should wait for the thread to exit, perhaps using 'pthread_join( thread );' this will assure the printf() is fully executed in the thread. 2) the returned value(==0) from pthread_create() should be checked to assure the operation was successful. – user3629249 May 22 '15 at 17:57

2 Answers2

6

You can't say when the thread starts to run, it might not start until after you return from main which means the process will end and the thread with it.

You have to wait for the thread to finish, with pthread_join, before leaving main.

The third case, with the message from the thread printed twice, might be because the thread executes, and the buffer is written to stdout as part of the end-of-line flush, but then the thread is preempted before the flush is finished, and then the process exist which means all file streams (like stdout) are flushed so the text is printed again.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    I think the OP is tripping. – Carcigenicate May 21 '15 at 13:42
  • I understand what you said about the first option, but the third option is still unclear to me... – Asaf Kahlon May 21 '15 at 13:48
  • 2
    @Carcigenicate OP isn't. It's a known issue see [this answer](http://stackoverflow.com/questions/26211423/unexpected-output-in-a-multithreaded-program) and this [bug report](https://sourceware.org/bugzilla/show_bug.cgi?id=14697). – P.P May 21 '15 at 13:48
  • @BlueMoon I was actually just coming back to say "nvm". Thanks for the link. – Carcigenicate May 21 '15 at 13:49
  • 1
    @Joachim why would it be undefined? It's the same as any thread calling `exit()` anytime. – P.P May 21 '15 at 13:51
  • Well, since process termination is an OS action, it's defined by the OS action - all process threads get stopped, all user resources freed, all kernel process resouces freed, process no longer exists. If there are unwanted consequences at user level, the overall design is inadequate since processes may get stopped at any time, eg. by 'kill -9', Task Manager or power fail. 'You have to wait for the thread to finish, with pthread_join, before leaving main' - no, you don't, not with any non-trivial OS. – Martin James May 21 '15 at 16:48
  • 1
    Besides joining the threads alternativly one could leave `main()` using `pthread_exit()`. – alk May 21 '15 at 17:09
4

For output 1:

your main function only create a pthread, and let it run without waiting for it to finish.

When your main function return, Operating system will collect back all the resources assigned to the pprocess. However the newly created pthread might have not run.

That is why you only got HERE.

For output 2:

your newly created thread finished before main function return. Therefore you can see both the main thread, and the created thread's output.

For output 3

This should be a bug in glibc. Please refer to Unexpected output in a multithreaded program for details.

To make the program always has the same output

pthread_join is needed after pthread_create

Community
  • 1
  • 1
Kun Ling
  • 2,211
  • 14
  • 22
  • Thank you for the answers for outputs 1 and 2. About output 3: I just run the program multiple times and saw that this option exists. I really don't have more information... – Asaf Kahlon May 21 '15 at 13:59
  • I Update the answer since output 3 seems to be a bug in glibc. – Kun Ling May 21 '15 at 14:03
  • Besides joining the threads alternativly one could leave `main()` using `pthread_exit()`. – alk May 21 '15 at 17:06
  • Another related SO question: http://stackoverflow.com/questions/13550662/pthread-one-printf-statement-get-printed-twice-in-child-thread – Michael Burr May 22 '15 at 22:00