Pthread_join () for asynchronous threads

I wrote a simple demo to understand the pthread_join () function.

I know how to use the pthread_condition_wait () function to allow asynchronous streaming, but I'm trying to figure out how I can do a similar job using the pthread_join () function.

In the program below, I am passing the Thread 1s ID function to Thread 2s. Inside the Thread 2s function, I call the pthread_join () function and pass the Thread 1s id. I expected this to cause Thread 1 to start first and then for Thread 2 to start the second, but what I get is that they both start at the same time.

Is it because only one thread can use the pthread_join () function at a time and that I am already using the pthread_join () function when I call it from the main thread?

#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

+3


source to share


3 answers


When threads are created with pthread_create()

, both threads start execution at the same time, and there is no fixed order in their execution order. The order depends on the OS layout and the number of available processors, etc. In any case, it is impossible to determine and that's the point of the flows anyway.

What happens when you call is the pthread_join()

caller is waiting for the thread for which the connection ends. Therefore the main thread waits for completion thread1

and then for thread2

. But while the main one is waiting thread1

, thread2

it may have finished executing and has already completed. In this case, it pthread_join(thread2, NULL);

will return immediately.



You have a big problem in your code. You pass the thread1

ID to thread2

. But if thread1

execution finishes before starting thread2

, you will use an invalid thread ID, resulting in undefined behavior. Another problem is that your main thread was thread2

trying to join thread1

. In short, pthread_join()

it is not a suitable tool for synchronizing across multiple threads. As you said, you are using condition variables / mutexes for this purpose.

I suggest you remove pthread_join()

from thread2

to fix undefined behavior and if you want serial execution of threads then you need to create threads one by one and let them and wait until the previous thread completes ( pthread_join()

). But there is very little practical use for this. Or let the threads wait on the conditional variable before doing anything, and you can make the threads exchange in the order you want the conditional variables to be used.

+6


source


You are calling undefined behavior. man page: http://man7.org/linux/man-pages/man3/pthread_join.3.html

Joining with a thread that has previously been joined results in undefined behavior.

      



Also, the first thread can complete excrement before the second thread. If you need something like this, it is much better to use pthread_cond_wait()

.

+3


source


From the pthread_join man page (emphasis mine):

If multiple threads try to join the same thread at the same time, the results are undefined. If the thread calling pthread_join () is canceled, then the target thread will remain connected (i.e., it will not be disconnected).

It seems that you are exactly in this situation, with main thread and thread 2 trying to execute pthread_join

thread 1.

You must clearly define for each thread one "owner thread" that is responsible for managing it. The chain of responsibility must form a hierarchical thread tree (i.e. no loops or multiple parents).

+1


source







All Articles