Why do we need pthread_join?

In simple words pthread_join makes the calling thread wait till the newly created thread returns. How this helps?

Let’s take an example as below:


#include
#include
#include
#include 

/* Prototypes */
void * thread_func1(void *);
void * thread_func2(void *);
void manipVal(int);

int var = 0;
pthread_mutex_t m;

void * thread_func1(void *arg)
{
printf("Hello World again\n");
}

void * thread_func2(void *arg)
{
printf("Hello World again and again\n");
return NULL;
}

void manipVal(int val)
{
pthread_mutex_lock(&m);
var = val;
pthread_mutex_unlock(&m);
}

int main(void)
{
pthread_t thread1, thread2;
int ret;

ret = pthread_create(&thread1, NULL, thread_func1, NULL);
if(ret < 0)
printf("Thread creation failed\n");

ret = pthread_create(&thread2, NULL, thread_func2, NULL);
if (ret < 0)
printf("Failed to create thread\n");

printf("Hello world!\n");
return 0;
}

The source can be found here as well pthread.c.

Now, if you run the program you will see something like this in the output window:

pthread.png

This is an output from a Codeblocks program using gcc compiler and running on a Windows PC.

Now, as can be seen in the output the the prints from the thread function thread_func1 and thread_func2 are missing, only the print from the main() function is coming on the console which is “Hello World”.

The reason there is no prints from the newly created threads is that the main function didn’t wait enough for the newly created threads to do anything and exited immediately after the last instruction executed in main.

pthread_join helps to make the main thread wait till the newly created threads are finished what they are supposed to finish which is printing their own prints.

So lets modify the program and add pthread_join for both the threads and see how that helps. Look at the below modified program again:


#include
#include
#include
#include 

/* Prototypes */
void * thread_func1(void *);
void * thread_func2(void *);
void manipVal(int);

int var = 0;
pthread_mutex_t m;

void * thread_func1(void *arg)
{
printf("Hello World again\n");

return NULL;
}

void * thread_func2(void *arg)
{
printf("Hello World again and again\n");

return NULL;
}

void manipVal(int val)
{
pthread_mutex_lock(&m);
var = val;
pthread_mutex_unlock(&m);
}

int main(void)
{
pthread_t thread1, thread2;
int ret;

ret = pthread_create(&thread1, NULL, thread_func1, NULL);
if(ret < 0)
printf("Thread creation failed\n");

ret = pthread_create(&thread2, NULL, thread_func2, NULL);
if (ret < 0)
printf("Failed to create thread\n");

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

printf("Hello world!\n");
return 0;
}

This program source code can be download from here as well pthread_join.c.

Now run the program again and see the output as below:

pthread

Now as you can see there are prints from the threads as well as from the main function. But if you notice the outputs are all mixed up with one another. What is the reason? The reason is printf function is a buffered function and as threads share the buffer the output from the thread gets mixed up with one another. So to get rid of this problem you can use an unbuffered mechanism for outputting your prints. We can use write system call directly for this problem. Let’s try as below:


#include
#include
#include
#include 

/* Prototypes */
void * thread_func1(void *);
void * thread_func2(void *);
void manipVal(int);

int var = 0;
pthread_mutex_t m;

void * thread_func1(void *arg)
{
char buff[1024];
//manipVal(10);
//printf("%d\n", var);

sprintf(buff, "Hello World again\n");
write(2, buff, 18);

return NULL;
}

void * thread_func2(void *arg)
{
char buff[20124];
//manipVal(20);
//printf("%d\n", var);

sprintf(buff, "Hello World again and again\n");
write(2, buff, 28);

return NULL;
}

void manipVal(int val)
{
pthread_mutex_lock(&m);
var = val;
pthread_mutex_unlock(&m);
}

int main(void)
{
pthread_t thread1, thread2;
int ret;

ret = pthread_create(&thread1, NULL, thread_func1, NULL);
if(ret < 0)
printf("Thread creation failed\n");

ret = pthread_create(&thread2, NULL, thread_func2, NULL);
if (ret < 0)
printf("Failed to create thread\n");

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

printf("Hello world!\n");
return 0;
}

The program can be found here as well pthread_join_write.c.

Now look at the output again:

pthread.png

Now, you should be fairly happy about the output from the threads.

 

 

 

 

 

 

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s