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().
Related
This is the code I have so far for the newly modified version of nosmp.c.
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
lng t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
The code below is the old nosmp.c code:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
void* thread(void* arg)
{
printf("\n Entered.., %c\n", *((char*)arg));
//critical section
sleep(4);
printf("\n Just Exiting.., %c\n", *((char*)arg));
}
int main()
{
pthread_t t1,t2;
pthread_create(&t1,NULL,thread,"1");
sleep(2);
pthread_create(&t2,NULL,thread,"2");
pthread_join(t1,NULL);
pthread_join(t2,NULL);
return 0;
}
For the modified version of the code above, I am trying to figure out where I would add the semaphore system calls into their proper lines to ensure that two threads will enter the critical section in order.
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.
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.)
}
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);
I have a big problem, I can't figure out why mutexes in C don't work as I expect.
This is my code:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
pthread_t mythread;
pthread_mutex_t mymutex;
void *anotherFunc(void*)
{
pthread_mutex_lock(&mymutex);
for(int i = 0; i < 100; i++)
printf("anotherFunc\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
void *func(void*)
{
pthread_mutex_lock(&mymutex);
for(int i = 0; i < 100; i++)
printf("func\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mymutex, NULL);
pthread_create(&mythread, NULL, func, NULL);
pthread_create(&mythread, NULL, anotherFunc, NULL);
pthread_mutex_destroy(&mymutex);
pthread_exit(NULL);
return EXIT_SUCCESS;
}
What I expect to happen is the program to print first 100 "func" messages and then 100 "anotherFunc" messages. What I expect is execution to reach func and lock the mutex. When the execution reaches anotherFunc, I expect to wait until func unlocks the mutex. But I get interfered messages like
func
func
func
anotherFunc
anotherFunc
anotherFunc
func
anotherFunc
I don't understand how this thing works. Please help!
pthread_create(&mythread, NULL, func, NULL);
pthread_create(&mythread, NULL, anotherFunc, NULL);
pthread_mutex_destroy(&mymutex);
You're destroying the mutex before the threads are done with it, so all bets are off. You'll probably want to pthread_join the 2 threads before destroying it.
I got few comiplation errors
I couldn't declare int i in for loop
Used an argument name arg as an argument for threads "func" and "anotherFunc"
I have used pthread_join before destroying the mutex.
In this way I am destroying my mutex "mymutex" after both threads "func" and "anotherFunc" have completed their execution
Also each threads now has their own thread id "mythread1" and "mythread2" so in this way I can use pthread_join() function for each thread
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
pthread_t mythread1, mythread2;
pthread_mutex_t mymutex;
void *anotherFunc(void *arg)
{
pthread_mutex_lock(&mymutex);
int i;
for(i = 0; i < 100; i++)
printf("anotherFunc\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
void *func(void *arg)
{
pthread_mutex_lock(&mymutex);
int i;
for(i = 0; i < 100; i++)
printf("func\n");
pthread_mutex_unlock(&mymutex);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_mutex_init(&mymutex, NULL);
pthread_create(&mythread1, NULL, func, NULL);
pthread_create(&mythread2, NULL, anotherFunc, NULL);
pthread_join(mythread1, NULL);
pthread_join(mythread2, NULL);
pthread_mutex_destroy(&mymutex);
return EXIT_SUCCESS;
}