phtread_join() will return through ptr what corresponding thread passes to pthread_exit(). Each thread is working independently and computes own set of primes, so, each thread should create own array and after all threads are joined you will print results of each array. To be able to return result set of primes and its count, we have to use own struct type:
struct comp_result {
unsigned *p_arr;
unsigned count;
};
I will illustrate the way Without locking:
compute_thread (...) {
...
struct comp_result *p_res = malloc(sizeof(struct comp_result));
p_res->p_arr = NULL;
p_res->count = 0;
for (num = start; num < end; num++) {
if (is_prime(num)) {
p_res->count++; /// increment number of primes and expand our storage
p_res->p_arr = realloc(p_res->p_arr, p_res->count*sizeof(int));
p_res->p_arr[p_res->count-1] = num; // save prime in result array
}
}
// pass pointer to per-thread result data
pthread_exit(p_res);
}
main () {
.... // create threads
....
for (i = 0; i < num_of_threads; i++) {
struct comp_result *p_res;
// retrieve and print array from i-thread
pthread_join(tids[i], &p_res);
for (num = 0; num < p_res->count; num++) {
printf(" %d ", p_res->p_arr[num]);
}
free(p_res->p_arr);
free(p_res);
}
}
The illustration with locking needs one more struct type since we will pass pointer to result shared data into each thread:
struct control {
unsigned start;
unsigned end;
struct comp_result *p_res;
}
compute_thread (ptr) {
struct control *p_cont = (struct control*)ptr;
// retrieve the pointer to shared, but be accurate with it!
struct comp_result *p_res = p_cont->p_res;
// initialize lock
pthread_mutex_init(&p_res->lock, NULL);
...
for (num = p_cont->start; num < p_cont->end; num++) {
if (is_prime(num)) {
pthread_mutex_lock(&p_control->lock);
// modify shared data with locking
p_res->count++; /// increment number of primes and expand our storage
p_res->p_arr = realloc(p_res->p_arr, p_res->count*sizeof(int));
p_res->p_arr[p_res->count-1] = num; // save prime in result array
pthread_mutex_unlock(&p_control->lock);
}
}
pthread_exit(NULL);
}
main () {
//create one shared data and initialize it:
struct comp_result *p_res = malloc(sizeof(struct comp_result));
p_res->p_arr = NULL;
p_res->count = 0;
for (i = 0; i < num_of_threads; i++) {
// create per-thread control data:
struct control *p_control = malloc(sizeof(struct control));
p_control->start =
p_control->end =
p_control->p_res = p_res;
pthread_crate(&tids[i], NULL, compute_thread, p_control);
}
....
for (i = 0; i < num_of_threads; i+++) {
pthread_join(tids[i], NULL);
}
// now all threads are completed and we are ready to read result:
for (num = 0; num < p_res->count; num++) {
printf(" %d ", p_res->p_arr[num]);
}
}