Thread struct as function parameter C
Solution 1
I recommend you to read http://www.advancedlinuxprogramming.com/alp-folder/alp-ch04-threads.pdf
And here what you wanted:
#define N 5
typedef struct thread {
pthread_t thread_id;
int thread_num;
// int thread_sum;
} ThreadData;
void *thread_start(void *thread)
{
ThreadData *my_data = (ThreadData*)thread;
//there is no guarantee that prints will be in order
// we will use its initial thread->num ,cause it differs for each thread
//plus you will see how threads will behave
int order=my_data->thread_num;
printf("%i) before num T: %i\n",order, my_data->thread_num);
my_data->thread_num=4;
printf("%i) after assignment num T: %i\n",order ,my_data->thread_num);
return NULL;
}
int main(int argc, char *argv[])
{
int i;
ThreadData thread[N];
for(i=0; i<N; i++)
{
thread[i].thread_num=i;
pthread_create(&(thread[i].thread_id), NULL, thread_start, (void *)(thread+i));
}
//wait for all threads
for (i = 0; i < N; i++)
pthread_join(thread[i].thread_id, NULL);
//print results of each thread
for (i = 0; i < N; i++)
printf(" %i)thread: number %i\n",i,thread[i].thread_num);
return 0;
}
Solution 2
I can see multiple mistakes in your code.
First you have your pointers wrong. In the first example, it is enough to pass &pthread_data
to pthread_create
, &thread
is the address of the thread
pointer, so you are passing struct thread **
to your function instead of struct thread *
. In the second example you should use (void *) thread[i]
. &thread[i]
is again struct thread **
.
When you want each thread to write to its own thread data, then you should make an array of thread data, so that each thread has its own piece, else you will run into race conditions.
As others have already pointed out, you should call pthread_join
before calling printf
to ensure that the main thread will wait for all worker threads.
Also note that if you are calling pthread_join
from other function that the one that spawned those threads, you have to ensure that the array of tread data will not go out of scope (in this case it would be probably better to use malloc
or a global array).
Related videos on Youtube
ganlub
I am a freelance developer who believes in smart coding and beautiful design. I show my passion for every project in the websites and applications I build.
Updated on September 29, 2022Comments
-
ganlub over 1 year
I'm having a trouble passing a struct pointer into a function because I'm a bit confused with those pointers and references. I want to modify the
thread.thread_num
value from thethread_start
function.#include <stdio.h> #include <stdlib.h> //malloc, free #include <pthread.h> #define N 5 // void *malloc(size_t); struct thread { pthread_t thread_id; int thread_num; // int thread_sum; }; void *thread_start(void *thread) { struct thread *my_data; my_data = (struct thread *)thread; printf("num T: %i\n", my_data->thread_num); my_data->thread_num=4; printf("num T: %i\n", my_data->thread_num); return NULL; } int main(int argc, char *argv[]) { int i; struct thread pthread_data; struct thread *thread = &pthread_data; thread->thread_num=2; pthread_create(&thread->thread_id, NULL, thread_start, (void *)&thread); printf("num: %i\n",thread->thread_num); pthread_exit(NULL); return 0; }
But the value that print the main doesn't change (2).
And then I want to create an array of thread struct, but I don't know how exactly do that: I guess it should be something like this:
int main(int argc, char *argv[]) { int i; struct thread pthread_data; struct thread *thread[N-1] = &pthread_data; // I don't know how to manage this. for(i=0; i<N; i++) { thread->thread_num=i; pthread_create(&thread[i]->thread_id, NULL, thread_start, (void *)&thread[i]); printf("num %i: %i\n",i,thread[i]->thread_num); } pthread_exit(NULL); return 0; }
Any thoughts?
-
hyde over 10 yearsIt's not this, but a simple race condition,
main
prints before the thread modifies. -
David Schwartz over 10 years@hyde He has a race condition, but this is the answer to his question.
-
hyde over 10 years"But the value that print the main doesn't change" part certainly happens before the pointer in the thread becomes dangling.
-
David Schwartz over 10 years@hyde Maybe, maybe not. It's undefined behavior, so it's hard to be sure. I took "I want to modify the thread.thread_num value from the thread_startfunction." as his primary question, and the answer is that he can't because it's not guaranteed to exist.
-
hyde over 10 yearsWell, this is getting argumentative, but... fixing the race condition would implicitly fix the dangling pointer UB, but fixing just the danging pointer UB would not necessarily change the output. But the main thing I object is implying, that using local variables of
main
is problem. It is not, it's perfectly fine in a normal application. The problem is allowingmain
to exit while other threads are still running, not usingmain
local variable.