1

I'm having trouble understanding the pthread_join() function because of the results I am getting.

If pthread_join() is supposed to pause the calling thread until the thread of the given thread id finishes it's job then why does the following code not do Thread 1 work first then do Thread 2 work. They are both happening concurrently.

If I take out the two pthread_join() lines (from main) the program terminates and nothing happens. Does this mean the main thread is the calling process of both join functions and it is the main thread who is waiting for the other two newly created threads to finish?

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

void *functionCount1();
void *functionCount2(void*);

int main()
{

    /* 
        How to Compile
         gcc -c foo
         gcc -pthread -o foo foo.o
    */

    printf("\n\n");

    int rc;
    pthread_t thread1, thread2;

    /* Create two thread --I took out error checking for clarity*/
    pthread_create( &thread1, NULL, &functionCount1, NULL)
    pthread_create( &thread2, NULL, &functionCount2, &thread1)

    pthread_join( thread1, NULL);
    pthread_join( thread2, NULL);

    printf("\n\n");
    exit(0);
}

void *functionCount1()
{

    printf("\nFunction 1");
        sleep(5);
    printf("\nFunction 1");

    return(NULL);
}

void *functionCount2(void* argument)
{

    //pthread_t* threadID = (pthread_t*) argument;

    //pthread_join(*threadID, NULL);

    printf("\nFunction 2");
        sleep(5);
    printf("\nFunction 2");

    return(NULL);
}

Output:

enter image description here

Output with sleep commented out:

enter image description here

Can someone explain why pthread_join is not doing what the documentation leads you to believe?

Kyle Bridenstine
  • 6,055
  • 11
  • 62
  • 100
  • Your question doesn't make sense. It's doing exactly what the documentation leads you to believe. Why would you expect that calling `pthread_join` will pause any thread other than the thread calling it? – David Schwartz Nov 12 '14 at 19:03
  • 1
    'Does this mean the main thread is the the calling process of both join functions and it is the main thread who is waiting for the other two newly created threads to finish?' Yes. – Martin James Nov 12 '14 at 19:03
  • Your `void *functionCount1()` is not a valid thread procedure, it must take a single parameter of type `void*`; doing otherwise is Undefined Behavior (which might appear to work for now, but it could be silently corrupting memory, and it may break horribly in future versions of your OS). – Adam Rosenfield Nov 13 '14 at 05:57
  • @Adam Rosenfield Thanks that is good to know. – Kyle Bridenstine Nov 13 '14 at 05:58

1 Answers1

3

if pthread_join() is supposed to pause the calling process until the thread of the given thread id finishes it's job...

That is not quite correct: pthread_join() is supposed to pause the calling thread, not the calling process. Since you are calling pthread_join() from the thread running your main function, the other two threads are allowed to proceed concurrently, i.e. the way they do in your example.

The reason the code that you commented out does not work is that you are passing a pointer to pthread_t, but then you cast it to plain pthread_t inside the thread running function (i.e. pthread_t* becomes pthread_t). Fixing this problem should allow your code to produce the results that you expect:

void *functionCount2(void* argument)
{
    pthread_t *threadID = (pthread_t*) argument;
    pthread_join(*threadID, NULL);
    printf("\nFunction 2");
    sleep(5);
    printf("\nFunction 2");
    return(NULL);
}

In addition, you should remove pthread_join( thread1, NULL); from your main function, because the results of multiple simultaneous calls to pthread_join() specifying the same target thread are undefined.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Ok so my assumption was right that its the main thread calling those two lines. So shouldn't I be able to uncomment the two lines in my thread 2 function and have thread 2 wait on thread 1? – Kyle Bridenstine Nov 12 '14 at 19:03
  • @Mr.Tea There's really no such thing as a "main thread". All threads are essentially equal. The only thing that's special is returning from `main`. – David Schwartz Nov 12 '14 at 19:04
  • @Mr.Tea See the update for the reason why the code that you commented out does not do what it should (you are doing the type cast incorrectly.) – Sergey Kalinichenko Nov 12 '14 at 19:06
  • @dasblinkenlight I updated my post again (really sorry I keep doing that to you) but the output after the fix was still concurrent, your answer did resolve the `sleeping` issue where I had to exit with `ctr + z`. – Kyle Bridenstine Nov 12 '14 at 19:12
  • @Mr.Tea You are better off asking a new question - right now it is **very** hard to figure out what you are actually asking, and what your code looks like now - especially since you didn't post it. – nos Nov 12 '14 at 19:30
  • I can ask a new question. I have the full code posted though. – Kyle Bridenstine Nov 12 '14 at 19:31
  • 2
    @Mr.Tea Please do that in the future, instead of changing an existing question that much. Your code now calls pthread_join on thread1 2 places, one in main and one in functionCount2, which you can't do - only 1 thread at a time can wait for another. – nos Nov 12 '14 at 19:39
  • Thank you, I'm currently writing a question on that part. Maybe I should stop if you just answered it partially. – Kyle Bridenstine Nov 12 '14 at 19:41