View Single Post
Old 02-05-2005, 02:10 PM   #1 (permalink)
SiNai
Dreams In Digital
 
SiNai's Avatar
 
Location: Iowa
[C] Problems with threading

So, I'm taking a course on Operating Systems, and just got a (relatively simple) project to complete. Catch is, it's in C, and I don't know C, and I have to use Unix, which I'm catching on to, at least. I know Java and Ada. The task is simple: I need to take the program supplied, and make it threaded. At least 3 threads need to be running concurrently. Anyway.. here is the code I get:

Code:
/* Programming Project #1
 * Operating Systems, Spring 2005*/
#include <pthread.h>
#include <stdio.h>
#include <math.h>

/* This program successively tests integers for prime numbers.  Return the Nth
prime number, where N is the value pointed to by *ARG. */

void * compute_prime (void * arg)
{
  int candidate = 2;
  int n = *((int*) arg); /* The parameter passed here is only an int so
                            we can abuse this feature by straight casting */

  while (1) {
    int factor;
    int is_prime = 1;
    int upper_limit = (int) sqrt((double)candidate); /*You need only test up to sqrt(x)
                                                     divisiors of x */
    /* Test primality by successive division */
    for (factor = 2; factor <= upper_limit; ++factor)
      if (candidate % factor == 0) {
        is_prime = 0; /*false*/
        break;
      }

    /* Is this the prime number that we're looking for? */
    if (is_prime) {
      if (--n == 0)
        /* Return the desired prime number as the thread return value */
        return (void*) candidate;
    }
    ++candidate;
  }


  return NULL;

}

int main () {
  pthread_t thread;
  int which_prime = 5000;
  int prime;

  /* Start the computing thread, up to the "which prime" prime number. */
  pthread_create(&thread, NULL, &compute_prime, &which_prime);

  /* Wait for the prime number thread to complete, and get the result */
  pthread_join(thread, (void*) &prime);

  /* Print the largest prime that it computed */
  printf("The %dth prime number computed is %d.\n", which_prime, prime);
  return 0;
}
So, I worked around a little bit, and here's what I got compiled:

Code:
struct ranges
{
  int begin;
  int end;
};

void * compute_prime (void * params)
{
  struct ranges* p = (struct ranges*) params;
  int candidate = p -> begin;
  int n = p -> end; /* The parameter passed here is only an int so
                          we can abuse this feature by straight casting */



  while (1)
  {
    int factor;
    int is_prime = 1;
    int upper_limit = (int) sqrt(candidate); /*You need only test up to sqrt(x)
                                                     divisiors of x */

    /* Test primality by successive division */
    for (factor = 2; factor <= upper_limit; ++factor)
    {
      if (candidate % factor == 0)
      {
        is_prime = 0; /*false*/
        break;
      }
    }

    /*At this point, we know primality*/
    /* Is this the prime number that we're looking for? */
    if (is_prime)
    {
      if (--n == 0)
        /* Return the desired prime number as the thread return value */
        return (void*) candidate;
    }
    ++candidate;
  }


  return NULL;
}

int main () {
  pthread_t thread1, thread2, thread3;
  int prime1, prime2, prime3;

  int which_prime     =    6;
  int begin           =    2;
  int final_result    =    0;
  int first_third     = which_prime/3;
  int final_third     = (first_third * 2);

  struct ranges thread1_args, thread2_args, thread3_args;
  thread1_args.begin = begin;
  thread1_args.end   = first_third - 1;
  thread2_args.begin = first_third;
  thread2_args.end   = final_third - 1;
  thread3_args.begin = final_third;
  thread3_args.end   = which_prime -1;

  /* Wait for all threads to complete, and grab the values when they are done */
  pthread_join(thread1, (void*) &prime1);
  pthread_join(thread2, (void*) &prime2);
  pthread_join(thread3, (void*) &prime3);


  /* Start 3 threads, each computes the amount of primes in one third of which_prime */
  pthread_create(&thread1, NULL, &compute_prime, &thread1_args);
  pthread_create(&thread2, NULL, &compute_prime, &thread2_args);
  pthread_create(&thread3, NULL, &compute_prime, &thread3_args);

printf("first thread %d .\n", prime1);
  printf("second thread %d .\n", prime2);
  printf("third thread %d .\n\n", prime3);
  /* Print the largest prime that it computed */
  printf("The %dth prime number computed is %d.\n", which_prime, prime3);
  return 0;

}

I get a quick Seg Fault after running my program. I know it makes it to creating the threads, but never past creating all 4 threads, so the problem lies somewhere in there. Keep in mind I know nothing about C.

My first reaction to the Seg Fault was "Well, maybe final_result is being used before all threads have returned", but, pthread_join is supposed to wait until threads have finished before going on, right?

[edit]I'm almost certain now that my threads dont work right. Thinking I should add a field to my structs.. Or perhaps that this isn't where the threads should go in the first place..




[edit2]: Updated my attempt at code. Refer to my reply down the page..
__________________
I can't seem to remember now
What it was like- to live life, before you.. symbiont

Last edited by SiNai; 02-08-2005 at 02:02 PM..
SiNai is offline  
 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73