Unexpected output in pthread - c

Hello for above code in thread it is displaying 0 (tid = 0) instead of 8... what may be the reason ? In PrintHello function I am printing threadid but I am sending value 8 but it is printing 0 as output
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void *PrintHello(void *threadid)
{
int *tid;
tid = threadid;
printf("Hello World! It's me, thread #%d!\n", *tid);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t thread1,thread2;
int rc;
int value = 8;
int *t;
t = &value;
printf("In main: creating thread 1");
rc = pthread_create(&thread1, NULL, PrintHello, (void *)t);
if (rc)
{
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
printf("In main: creating thread 2\n");
rc = pthread_create(&thread1, NULL, PrintHello, (void *)t);
if (rc)
{
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
/* Last thing that main() should do */
pthread_exit(NULL);
}

The actual object that holds 8 is value which is local to your main function so accessing after main has exited is not valid.
You don't wait for your child threads to finish before they attempt to access this local variable so the behaviour is undefined.
One fix would be to make your main wait for it's child threads before exiting using pthread_join.
(I've assumed that you've made a typo in your second call to pthread_create and meant to pass thread2 instead of thread1.)
E.g.
/* in main, before exiting */
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);

Related

question on pthread_join() and pthread_detach()

I wrote this program to practice pthread system calls so I used some printing lines to check the results but they are escaped the output is:
Thread 1 created
Thread 2 created
test3
while I think it should be
thread 1 created
test2
thread 2 created
test3
test1
The order may change but I should have this lines so why it escape this print statements?
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void *function();
void *function2();
int main(int argc, char *argv[])
{
pthread_t tid;
int rc;
rc = pthread_create(&tid, NULL, function(), NULL);
if(rc > 0){
fprintf(stderr, "Error\n");
exit(1);
}
pthread_join(tid, NULL);
sleep(1);
printf("test1\n");
pthread_exit(NULL);
}
void *function(){
int rc;
pthread_t tid;
printf("Thread 1 created\n");
rc = pthread_create(&tid, NULL, function2(), NULL);
if(rc > 0){
fprintf(stderr, "Error\n");
exit(1);
}
printf("test2\n");
pthread_exit(NULL);
}
void *function2(){
pthread_detach(pthread_self());
printf("Thread 2 created\n");
printf("test3\n");
pthread_exit(NULL);
}
rc = pthread_create(&tid, NULL, function(), NULL);
You're trying to call pthread_create() with the pointer returned by calling function() as the function to run in the new thread (Remember, function arguments get evaluated before the function itself is called). Now, function() doesn't actually return any value, but it calls function2() in its body (while evaluating the arguments for another call to pthread_create()), which also doesn't return any value, but does call pthread_exit() instead. Since there's only one thread at that point because only the main process thread is running (pthread_create() hasn't actually been called yet; the call stack looks like main() -> function() -> function2()), the whole program then exits.
You need to call pthread_create() with pointers to function and function2, not the results of calling them:
rc = pthread_create(&tid, NULL, function, NULL);
etc.

pthread_detach doesn't change anything

I understand pthread_detach(pid) that: "storage for the thread thread can be reclaimed when that thread terminate" (as per http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_detach.html)
However, I understand that means that once the pid thread finishes executing, its memory will be freed, and we will not be able to run it again, or call join on it.
However, I tried the following code:
#include <stdio.h>
#include <pthread.h>
void* myFunction (void* arg)
{
printf("Hello World from thread!\n");
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, myFunction, NULL);
//pthread_join(tid, NULL);
int isDetached = -10;
isDetached = pthread_detach(tid);
printf("Is my thread detached: %d\n", isDetached);
int i;
for (i = 0; i<15; i++)
printf("%d\n", i);
pthread_create(&tid, NULL, myFunction, NULL);
pthread_join(tid, NULL);
for (i = 0; i<15; i++)
printf("%d\n", i);
return 0;
}
And I get the following:
If I understand correctly, since I did pthread_detach(tid), I should not be able to be able to do
pthread_create(&tid, NULL, myFunction, NULL);
pthread_join(tid, NULL);
after it, yet I did and it works perfectly. So, what is really the purpose of doing othread_detach(pid) if we can still run the thread and join it?
Thanks a lot!
pthread_detach simply tells your program that the current instance of tid will not join, (pthread_join) again, and frees up any pthread handles & objects on the tid instance.
Since you called pthread_detach if you try to pthread_join that thread it will not since it has been released and disposed of.
I've added the pthread_join to your code right after the detach call and you can see nothing happens as expected.
#include <stdio.h>
#include <pthread.h>
void * myFunction (void *arg)
{
printf ("Hello World from thread!\n");
}
int main ()
{
pthread_t tid;
pthread_create (&tid, NULL, myFunction, NULL);
//pthread_join(tid, NULL);
int isDetached = -10;
isDetached = pthread_detach (tid);
printf ("Is my thread detached: %d\n", isDetached);
/* ADDED FOR STACK OVERFLOW */
pthread_join (tid, NULL);
int i;
for (i = 0; i < 15; i++)
printf ("%d\n", i);
pthread_create (&tid, NULL, myFunction, NULL);
pthread_join (tid, NULL);
for (i = 0; i < 15; i++)
printf ("%d\n", i);
return 0;
}
I'm not sure what the confusion is but if you were expecting a different behavior when you called pthread_create a second time; note, this is really creating a fresh instance of tid for you. Therefore your second join call runs the thread.
pthread_t tid;
pthread_create(&tid, NULL, myFunction, NULL);
This creates a new thread and subsequent call topthread_detach(pid) detaches the thread created. Now
pthread_create(&tid, NULL, myFunction, NULL);
This creates a new thread and subsequently you have called a join which basically waits for the completion of the newly created thread, not for the one which has been detached.
You can check the code attached below. When you run this code the thread which has been detached is printing even after join is called i.e myfunc1 is still printing after the pthread_join.
#include <stdio.h>
#include <pthread.h>
void *myFunction2 (void *arg)
{
printf("Hello World from func2!\n");
}
void *myFunction1 (void *arg)
{
while(1) {
printf("Hello World from func1\n");
}
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, myFunction1, NULL);
//pthread_join(tid, NULL);
int isDetached = -10;
isDetached = pthread_detach(tid);
printf("Is my thread detached: %d\n", isDetached);
int i;
pthread_create(&tid, NULL, myFunction2, NULL);
pthread_join(tid, NULL);
for (i = 0; i<15; i++)
printf("%d\n", i);
return 0;
}
Your variable, tid, is not a thread. Your program does not start one thread two times, it creates two completely different threads.
The actual threads are objects that exist in the operating system. Your tid variable is just a "handle" that you can use to interact with a thread. Your second call to pthread_create(&tid,...) is re-using the handle variable, pointing it to a new, different thread.

Is pthread_join a must when using pthread in linux?

I an learning pthread and I have a few questions.
Here is my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define NUM_THREADS 10
using namespace std;
void *PrintHello(void *threadid)
{
int* tid;
tid = (int*)threadid;
for(int i = 0; i < 5; i++){
printf("Hello, World (thread %d)\n", *tid);
}
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
int t;
int* valPt[NUM_THREADS];
for(t=0; t < NUM_THREADS; t++){
printf("In main: creating thread %d\n", t);
valPt[t] = new int();
*valPt[t] = t;
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)valPt[t]);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
The code runs well and I don't call pthread_join. So I want to know, is pthread_join a must?
Another issue, is:
valPt[t] = new int();
*valPt[t] = t;
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)valPt[t]);
equal to:
rc = pthread_create(&threads[t], NULL, PrintHello, &i);
It is not. But you need either pthread_exit() or pthread_join().
Here you called pthread_exit(), thats why the child threads continue execution even after the main thread terminates.
If there is any need for the main thread to wait till the child threads complete execution, you can use pthread_join().

Simple example for pthread_join deadlock

I am looking for a very simple example to demonstrate a deadlock using pthread_join; however, this is not trivial.
I started with this:
void* joinit(void* tid)
{
pthread_t* tid_c = (pthread_t*)tid;
int retval = pthread_join(*tid_c, NULL);
printf("In joinit: tid = %d, retval = %d \n", *tid_c, retval);
return NULL;
}
int main()
{
pthread_t thread1;
pthread_t thread2;
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
pthread_join(thread2, NULL);
return 0;
}
But however, it says 'EINVAL' (invalid argument) because thread2 is not yet specified when pthread_create for thread1 is called.
Any ideas?
If you're just wanting to demonstrate that a pthread_join can cause a deadlock, you could do something similar to the following code:
#include <stdio.h>
#include <pthread.h>
void* joinit(void* tid)
{
printf("In %#x, waiting on %#x\n", pthread_self(), (*((pthread_t*)tid)));
pthread_join((*((pthread_t*)tid)), NULL);
printf("Leaving %#x\n", pthread_self());
return NULL;
}
int main(void)
{
pthread_t thread1 = pthread_self();
pthread_t thread2;
pthread_create(&thread2, NULL, joinit, &thread1);
joinit(&thread2);
return 0;
}
This will cause the main thread to wait on the spawned thread and the spawned thread to wait on the main thread (causing a guaranteed deadlock) without the need for extra locking primitives to clutter up what you are trying to demonstrate.
And to answer some of your questions more directly:
it says 'EINVAL' (invalid argument) because thread2 is not yet specified when pthread_create for thread1 is called.
... and from one of your comments ...
I tried this and it worked, but the problem is, it only works SOMETIMES because sometimes I get EINVAL again.
In your code, you call pthread_create consecutively to spawn the 2 threads:
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
In your joinit code, you grab the thread handle passed in to join on:
pthread_t* tid_c = (pthread_t*)tid;
int retval = pthread_join(*tid_c, NULL);
The reason this sometimes works and others you'll get EINVAL has to do with time slices allocated to each thread's context and sequencing. When the first pthread_create is called you will have a valid handle to thread1 after it returns but the handle to thread2 is not valid yet, at least not until the 2nd pthread_create is called.
To this, when a thread is created, the act of the thread coming "alive" (i.e. the thread function actually running) could take some extra time even though the thread handle returned is valid. In these instances, there is a chance one thread can execute more code than might be "expected". In your code, both pthread_create functions might happen to have been called in the time slice allocated for the main thread which could give each spawned thread enough "time" before hitting the pthread_join statement allowing tid_c to point to a valid handle; in the EINVAL case, pthread_create(&thread1, NULL, joinit, &thread2) was called and the spawned thread hit the pthread_join(*tid_c, NULL) before pthread_create(&thread2, NULL, joinit, &thread1) could give thread2 a valid handle (causing the error).
If you wanted to keep your code similar to how it is now, you would need to add a lock of some sort to ensure the threads don't exit or call anything prematurely:
#include <stdio.h>
#include <pthread.h>
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void* joinit(void* tid)
{
/* this can be above the lock because it will be valid after lock is acquired */
pthread_t* tid_c = (pthread_t*)tid;
int retval = -1;
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
printf("%#x waiting on %#x\n", pthread_self(), *tid_c);
retval = pthread_join(*tid_c, NULL);
printf("In joinit: tid = %d, retval = %d \n", *tid_c, retval);
return NULL;
}
int main()
{
pthread_t thread1;
pthread_t thread2;
/* get the lock in the main thread FIRST */
pthread_mutex_lock(&lock);
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
/* by this point, both handles are "joinable", so unlock */
pthread_mutex_unlock(&lock);
/* can wait on either thread, but must wait on one so main thread doesn't exit */
pthread_join(thread2, NULL);
return 0;
}
Hope this can help.
The main reason for your error is that you have two threads each waiting for the same thread to terminate because of the call to pthread_join in main. Another problem is that you don't ensure each thread correctly sees the other thread's ID.
Fix it like this:
#include <stdio.h>
#include <pthread.h>
pthread_t thread1;
pthread_t thread2;
pthread_mutex_t mutex;
pthread_cond_t cond;
int go = 0;
void* joinit(void* ptr)
{
// wait until both thread IDs are known
pthread_mutex_lock(&mutex);
while (go == 0)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
pthread_t* tid_c = *((pthread_t**) ptr);
printf("About to wait\n");
int retval = pthread_join(*tid_c, NULL);
printf("In joinit: tid = %d, retval = %d \n", *tid_c, retval);
// tell the other threads we're done
pthread_mutex_lock(&mutex);
go++;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
// setup synchronization
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&thread1, NULL, joinit, &thread2);
pthread_create(&thread2, NULL, joinit, &thread1);
// tell the threads to go
pthread_mutex_lock(&mutex);
go = 1;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
// wait for both threads to finish
pthread_mutex_lock(&mutex);
while (go != 3)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
return 0;
}

pthread_join function kill the thread after execution or we need to call pthread_cancel/pthread_exit?

pthread_join() function kill the thread after execution or we need to call pthread_cancel()/pthread_exit()?
I am calling pthread_cancel()/pthread_kill() which is returning 3 ie no thread attached with thread_id.
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
void * run (void *);
int main() {
pthread_t p1, p2;
int a = 9;
printf("%d\n", pthread_create(&p1, NULL, &run, (void*)&p1));
printf("%d\n", pthread_create(&p2, NULL, &run, (void*)&p2));
printf("%d\n", pthread_join(p1, NULL));
//usleep(1000);
printf("%d\n", pthread_join(p2, NULL));
printf("before exit\n");
printf("%d\n", pthread_cancel(p1));
printf("after exit\n");
printf("%d\n", pthread_cancel(p2));
printf("both thread exited\n");
printf("%d\n", pthread_join(p1, NULL));
printf("%d\n", pthread_join(p2, NULL));
printf("terminated\n");
printf("%d\n", pthread_kill(p1, 0));
printf("%d\n", pthread_kill(p2, 0));
printf("ext\n");
printf("%d\n", pthread_join(p1, NULL));
printf("%d\n", pthread_join(p2, NULL));
printf("jion\n");
return 0;
}
void *run (void *p) {
int *i = (int*)p;
printf("created i = %d\n", *i);
}
This is the code i am using. in this pthread_cancel on wards all function returning 3 which means thread is being already killed.
pthread_join does not kill the thread, it waits for the thread to complete. If you want to kill a thread then use pthread_kill. But that has to be done before pthread_join, otherwise the thread has already exited.
pthread_cancel requests that the thread teminate at the next cancellation point, and is probably safer than using pthread_kill.
pthread_exit exits the current thread.
Some context would be nice... but if you're just waiting for a thread (presumably you only have one you care about) to terminate/return, then pthread_join is good enough.
The pthread_join() function waits for the thread specified by thread
to terminate. If that thread has already terminated, then pthread_join() returns
immediately.
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.html
Check the man page for usage/warnings.
After pthread_join() Add
/* Last thing that main() should do */
pthread_exit(NULL);
For more details pls refer here.
pthread_join() is used to make the main() thread wait till all the threads completes it's execution. Control reaches the pthread_join(), when that particular thread completes it's execution.
So if you try to cancel/kill that particular thread, error will be returned.
Sample Code
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 4
void *BusyWork(void *t)
{
int i;
long tid;
tid = (long)t;
printf("Thread %ld starting...\n",tid);
pthread_exit((void*) t); //Exits that current thread.
}
int main (int argc, char *argv[])
{
pthread_t thread[NUM_THREADS];
int rc;
long t;
void *status;
for(t=0; t<NUM_THREADS; t++) {
printf("Main: creating thread %ld\n", t);
rc = pthread_create(&thread[t], NULL, BusyWork, (void *)t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Wait for completion */
for(t=0; t<NUM_THREADS; t++) {
rc = pthread_join(thread[t], &status);
if (rc) {
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status);
}
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL); // Exits main thread.
}
For #Joachim Pileborg
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 4
void *BusyWork(void *t)
{
int i;
long tid;
tid = (long)t;
printf("Thread %ld starting...\n",tid);
for(i = 0; i <10000000; i++)
printf("\n Thread: %ld, %d", tid, i);
pthread_exit((void*) t); //Exits that current thread.
}
int main (int argc, char *argv[])
{
pthread_t thread[NUM_THREADS];
int rc;
long t;
void *status;
for(t=0; t<NUM_THREADS; t++) {
printf("Main: creating thread %ld\n", t);
rc = pthread_create(&thread[t], NULL, BusyWork, (void *)t);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
//printf("Main: program completed. Exiting.\n");
pthread_exit(NULL); // Exits main thread(work will be done).
//return 0;//( Threads will exit once main exits.)
}

Resources