I have wrote a simple program to play with pthreads .
Each thread receives as thread data a pointer to a struct and prints it. Then I have wrote a loop to dynamically allocate structs and then use the point in the thread creation.
The problem is, Why does all threads receive the same stuct although I have allocated different loops?
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
struct thread_data {
long thread_id;
int thread_sum;
};
void *PrintHello(void *threadData)
{
struct thread_data *data_input = (struct thread_data *)threadData;
printf("Hello World! It's me, thread #%ld! ,%d , pointer %d\n", data_input->thread_id, data_input->thread_sum, data_input);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];;
struct thread_data allData[NUM_THREADS];
int rc;
long t;
for (t = 0; t < NUM_THREADS; t++){
struct thread_data* data = malloc(sizeof(struct thread_data));
//allData[t].thread_id = t;
//allData[t].thread_sum = 100;
// struct thread_data data;
data->thread_id = t;
data->thread_sum = 0;
printf("In main: creating thread %ld , %d , %d\n", data->thread_id, data->thread_sum, &data);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&data);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
return 0;
}
on your code &data is of type struct thread_data **
replace this
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)&data);
by this
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)data);
also, you have to call free for each allocated memory inside (and just before pthread_exit) the PrintHello function
Directly use data
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
struct thread_data {
long thread_id;
int thread_sum;
};
void *PrintHello(void *threadData)
{
struct thread_data *data_input = (struct thread_data *)threadData;
printf("Hello World! It's me, thread #%ld! ,%d , pointer %d\n", data_input->thread_id, data_input->thread_sum, data_input);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];;
struct thread_data allData[NUM_THREADS];
int rc;
long t;
for (t = 0; t < NUM_THREADS; t++){
struct thread_data* data = malloc(sizeof(struct thread_data));
//allData[t].thread_id = t;
//allData[t].thread_sum = 100;
// struct thread_data data;
data->thread_id = t;
data->thread_sum = 0;
printf("In main: creating thread %ld , %d , %d\n", data->thread_id, data->thread_sum, &data);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)data);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
return 0;
}
Will ouput:
In main: creating thread 0 , 0 , -273609272
In main: creating thread 1 , 0 , -273609272
Hello World! It's me, thread #0! ,0 , pointer 13357072
In main: creating thread 2 , 0 , -273609272
In main: creating thread 3 , 0 , -273609272
In main: creating thread 4 , 0 , -273609272
Hello World! It's me, thread #2! ,0 , pointer 13357712
Hello World! It's me, thread #1! ,0 , pointer 13357392
Hello World! It's me, thread #4! ,0 , pointer 13359632
Hello World! It's me, thread #3! ,0 , pointer 13358032
Related
I am creating a pthread in the main function and calling another function called "PrintHello". the "PrintHello" function should print some messages. My threads are being created but i am guessing my function "PrintHello" isn't being called properly as the messages are not printing.
I have put another print command in "PrintHello" function and that is printing. That means the function is being called. but i can't figure out why the messages aren't printing.
char *messages[NUM_THREADS];
struct thread_data
{
int thread_id;
int sum;
char *message;
};
struct thread_data thread_data_array[NUM_THREADS];
void *PrintHello(void *threadarg)
{
printf("I am in PrintHello");
int taskid , sum;
char *hello_msg;
struct thread_data *my_data;
Sleep(1);
my_data = (struct thread_data *) threadarg;
taskid = my_data ->thread_id;
sum = my_data ->sum;
hello_msg = my_data ->message;
printf("Thread %d: %s Sum=%d\n", taskid , hello_msg , sum) ;
pthread_exit(NULL);
}
int main(int argc , char *argv[])
{
pthread_t threads[NUM_THREADS];
int *taskids[NUM_THREADS];
int rc, t, sum;
sum=0;
messages[0] = "English: Hello World!";
..............
messages[7] = "Latin: Orbis , te saluto!";
for(t=0;t<NUM_THREADS;t++)
{
sum = sum + t;
thread_data_array[t].thread_id = t;
thread_data_array[t].sum = sum;
thread_data_array[t].message = messages[t];
printf("Creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL , PrintHello , (void *) &thread_data_array[t]);
//rc = pthread_create(&threads[t], NULL , PrintHello , NULL);
if (rc)
{
printf("ERROR; return code from pthread_create() is %d \n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
The code should print out the hello messages.
I assume what's happening is your application is exiting before your threads have the chance to actually execute fully. Since you are storing each thread handle in the array of pthread_t threads[NUM_THREADS]; what you will need to do is upon creation a call to
pthread_join should be made which will allow the caller thread to be blocked until the thread has executed and returned. You can call pthread_join right after you call pthread_create or loop through all your handles and call pthread_join on each index in your array. If a call to pthread_join is made after the creation of each thread individually then a new thread will not spawn until the previous finishes. If you wish to execute them simultaneously then a loop after all the threads have been created would be the better option.
int main(int argc , char *argv[])
{
pthread_t threads[NUM_THREADS];
int *taskids[NUM_THREADS];
int rc, t, sum;
sum=0;
messages[0] = "English: Hello World!";
..............
messages[7] = "Latin: Orbis , te saluto!";
for(t=0;t<NUM_THREADS;t++)
{
sum = sum + t;
thread_data_array[t].thread_id = t;
thread_data_array[t].sum = sum;
thread_data_array[t].message = messages[t];
printf("Creating thread %d\n", t);
rc = pthread_create(&threads[t], NULL , PrintHello , (void *) &thread_data_array[t]);
//rc = pthread_create(&threads[t], NULL , PrintHello , NULL);
if (rc)
{
printf("ERROR; return code from pthread_create() is %d \n", rc);
exit(-1);
}
}
for(int index = 0; index < NUM_THREADS; ++index){
pthread_join(threads[index],NULL);//Wait for execution of each thread
}
}
You also don't need to call pthread_exit in your main. Typically that should be called in the thread you wish to terminate early where the value passed into pthread_exit can be retrieved from the second argument of pthread_join
Sorry for the late reply. I should have mentioned that i am using Windows. Anyway, i found out the problem. It is happening because of the "sleep" argument. For windows apparently it is different. so i changed my sleep argument to Sleep(1000), which apparently means 1 second in windows and that solved my problem. Thank you for all the replies.
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().
This is a program I did but the problem I am facing is that its not giving any output. When I try to run one thread its running perfectly else it doesn't. I tried to output it directly in the terminal which is working perfectly but when I try to output in the window using initgraph its not working.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include<graphics.h>
struct myran
{
int x;
int y;
};
void *print_message_function( void *ptr );
main()
{
int gd=DETECT,gm=VGAMAX;
initgraph(&gd,&gm,NULL);
pthread_t thread1, thread2;
const char *message1 = "Thread 1";
const char *message2 = "Thread 2";
int iret1, iret2;
struct myran a,b,c,d;
a.x=10;
a.y=10;
b.x=20;
b.y=20;
/* Create independent threads each of which will execute function */
iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) &a);
if(iret1)
{
fprintf(stderr,"Error - pthread_create() return code: %d\n",iret1);
exit(EXIT_FAILURE);
}
iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) &b);
if(iret2)
{
fprintf(stderr,"Error - pthread_create() return code: %d\n",iret2);
exit(EXIT_FAILURE);
}
printf("pthread_create() for thread 1 returns: %d\n",iret1);
//printf("pthread_create() for thread 2 returns: %d\n",iret2);
/* Wait till threads are complete before main continues. Unless we */
/* wait we run the risk of executing an exit which will terminate */
/* the process and all threads before the threads have completed. */
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
while(!kbhit())
;
closegraph();
exit(EXIT_SUCCESS);
}
void *print_message_function( void *ptr )
{
struct myran *ss;
ss=(struct myran *)ptr;
int `enter code here`x1,y1,x,y;
x1=ss->x;
y1=ss->y;
int i=0;
for(i=0;i<5;i++)
printf("%d \n", x1);
}
I'm writing a program that uses threads to compute the production of an array by a one dimensional array, all dimensions equal "n".
Each thread must compute the production of a row of the array with that one dimensional array.
The output i'm getting seems to have got addresses values instead of the values i already entered as the matrix elements.
What am i doing wrong?
here's the code i wrote:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define mat_dim 5
static struct param
{
int mat[mat_dim][mat_dim];
int vec[mat_dim];
int ind;
int alter[mat_dim];
};
void *Calculate_row(struct param tid)
{
int i;
for (i=0; i<5; i++) {
tid.alter[tid.ind] = tid.alter[tid.ind]+tid.mat[tid.ind][i]*tid.vec[i];
}
pthread_exit((void *)&tid);
}
int main (int argc, char *argv[])
{
pthread_t thread[mat_dim];
pthread_attr_t attr;
int rc;
long t;
void *status;
int th_array[5][5]={{1,4,3,5,1},{4,6,2,8,5},{3,5,1,3,6},{1,5,6,2,8},{4,7,5,3,6}};
int th_vec[5]={1,2,1,2,1};
struct param thread_parameter;
thread_parameter.mat[5][5]=th_array;
thread_parameter.vec[5]=th_vec;
int tmp[5]={0,0,0,0,0};
thread_parameter.alter[5]=tmp;
/* Initialize and set thread detached attribute */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for(t=0; t<mat_dim; t++) {
printf("Main: creating thread %ld\n", t);
thread_parameter.ind=t;
rc = pthread_create(&thread[t], &attr, Calculate_row,&thread_parameter);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Free attribute and wait for the other threads */
pthread_attr_destroy(&attr);
printf("the result vector is : ");
for(t=0; t<mat_dim; t++) {
rc = pthread_join(thread[t], NULL);
if (rc) {
printf("ERROR; return code from pthread_join() is %d\n", rc);
exit(-1);
}
printf("%d, ",thread_parameter.alter[t]);
}
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL);
}
you are calling rc = pthread_create(&thread[t], &attr, Calculate_row,&thread_parameter);
where
struct param thread_parameter;
and the function is void *Calculate_row(struct param tid)
it should be void *Calculate_row(struct param *tid)
as a pointer is passed and change all . to ->.
All these lines:
thread_parameter.mat[5][5]=th_array;
thread_parameter.vec[5]=th_vec;
thread_parameter.alter[5]=tmp;
are wrong. The array indexes go from 0 to 4, therefore by addressing the 5th element you're out of their bounds.
You're using pthread_create the wrong way. This is the prototype:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
Your Calculate_row receives a void* as a parameter, which needs to be cast to a (struct param *) and then dereferenced.
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);