Passing a parameter to pthread

I have the following code:

#include <stdlib.h> #include <stdio.h> #include <pthread.h> #define NUM_THREADS 100 struct thread_param { char *f1; char *f2; int x; }; void *thread_function(void *arg){ printf("%d\n", ((struct thread_param*)arg)->x); } int main(int argc, char *argvs[]){ int i, thread_cr_res = 0, thread_join_res; pthread_t *threads; threads = malloc(100 * sizeof(*threads)); if(threads == NULL){ fprintf(stderr,"MALLOC THREADS ERROR"); return (-1); } for(i = 0; i < NUM_THREADS; i++){ struct thread_param *tp; if((tp = malloc(sizeof(*tp))) == NULL){ fprintf(stderr,"MALLOC THREAD_PARAM ERROR"); return (-1); } tp->f1 = "f1"; tp->f2 = "f2"; tp->x = i; thread_cr_res = pthread_create(&threads[i], NULL, thread_function, (void*)tp); if(thread_cr_res != 0){ fprintf(stderr,"THREAD CREATE ERROR"); return (-1); } } return (0); } 

What I want to achieve is to print all numbers from 0 to 99, from streams. I am also experimenting how to pass a structure as an input parameter to a stream.

What I find in couriers is that not all numbers are shown, for example:

  ./a.out | grep 9 9 19 29 39 49 

And sometimes some numbers are displayed twice:

 ... 75 74 89 77 78 79 91 91 

Could you explain to me why this is happening? There are no errors.

LATEST PRODUCTS: I rewrote the code as @Yasir suggested using pthread_join . The new code is as follows:

 #include <stdlib.h> #include <stdio.h> #include <pthread.h> #define NUM_THREADS 100 struct thread_param { char *f1; char *f2; int x; }; void *thread_function(void *arg){ printf("%d\n", ((struct thread_param*)arg)->x); } int main(int argc, char *argvs[]){ int i, thread_cr_res = 0, thread_join_res; pthread_t *threads; threads = malloc(100 * sizeof(*threads)); if(threads == NULL){ fprintf(stderr,"MALLOC THREADS ERROR"); return (-1); } for(i = 0; i < NUM_THREADS; i++){ struct thread_param *tp; if((tp = malloc(sizeof(*tp))) == NULL){ fprintf(stderr,"MALLOC THREAD_PARAM ERROR"); return (-1); } tp->f1 = "f1"; tp->f2 = "f2"; tp->x = i; thread_cr_res = pthread_create(&threads[i], NULL, thread_function, (void*)tp); if(thread_cr_res != 0){ fprintf(stderr,"THREAD CREATE ERROR"); return (-1); } } /* Later edit, joining the threads */ for (i = 0; i < NUM_THREADS; i++){ thread_join_res = pthread_join(threads[i], NULL); if(thread_join_res != 0){ fprintf(stderr, "JOIN ERROR"); return (-1); } } return (0); } 

After:

 ./a.out | sort 0 1 10 11 12 13 14 15 16 17 18 19 2 20 21 22 23 24 25 26 27 28 29 3 30 31 32 33 34 35 36 37 38 39 4 40 41 42 43 44 45 46 47 48 49 5 50 51 52 53 54 55 56 57 58 59 6 60 61 62 63 64 65 66 67 68 69 7 70 71 72 73 74 75 76 77 78 79 8 80 81 82 83 84 85 86 87 88 89 9 90 91 92 93 94 95 96 97 98 99 

The code acts as it should. However, I cannot explain why the first version of the code displayed duplicates.

+4
source share
2 answers

Use int pthread_join(pthread_t thread, void **value_ptr) to wait for threads to finish so that they get all the results before the main thread exits. In addition, due to sizeof(*tp) you get the size of the pointer to this structure, whose length is 4 bytes in a 32-bit system. This could rewrite other structures in memory. sizeof(thread_param) will make more sense to me. Also tp->f1 = "f1"; refers to a single constant string. I. e. you do not save the string in the structure, but use the same buffer for all your thread_param structures. This would be unsafe if "f1" is a pointer to a variable buffer.

UPD: Yes, comments below the size are correct.

+2
source

The code acts as it should. However, I cannot explain why the first version of the code displayed duplicates.

This is probably due to the way stdio works on threads: in order not to damage the output (and any other thread in general), stdio uses locking. And if your main thread exits, bad things can happen, such as closing threads that need to be reopened / reset by other threads.

Please note that since the lock around the stdio function, the call to contention and printf () has become a kind of synchronization point that will change the way your program works.

+1
source

Source: https://habr.com/ru/post/1307219/


All Articles