user2817240
user2817240

Reputation: 195

C threads and joining

I have a question about C threads and their return value. My goal is to find all the prime numbers between a beginning number and an ending number. I will have 4 threads, and each thread does a quarter of the range.

So for example, the primes between 1 and 100.

All the prime numbers will be stored in an array and there will be a function that computes the primes.

My question is, when I join the threads

pthread_join(tids[i], ptr);

will ptr be a pointer to a combined array of ALL primes, 1 - 100?

Meaning if I use a for loop to print the values

printf("%d", ptr[i]); 

will it print all the primes from 1 - 100 as one big array?

Am I joining the 4 separate arrays?

Thank you

Upvotes: 2

Views: 578

Answers (1)

pmod
pmod

Reputation: 11007

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]);
      }
 } 

Upvotes: 2

Related Questions