3

I am trying to create a program in C to calculate the sum and the product via threads.It's my exercise for university.The problem I face is that when I run the program the thread doesn't seem to execute.I am stuck and I don't know how to proceed.

  #include <pthread.h>
  #include <stdio.h>
  #include <stdlib.h>
  int T1; //store the sum
  int *array; //global varriable

 void *Sum(void *N){ //function used by thread to calculate sum
     printf("I am the 1st thread i ll calculate the sum for you");
     long S=(long) N;
     int sum=0;
     int i;

     for (i=0; i<S; ++i){
       sum = sum +array[i];
     }  
     T1 = sum;
     pthread_exit(NULL);
}


int main(int argc, char *argv[])
{
  long N;
  printf("%d\n",T1);
  printf("give the size of the array please\n");
  scanf("%ld", &N);
  int *array= (int*) malloc((N)*sizeof(int)); // dynamic array
  int i;
  for (i=0; i<N; ++i)
  {
     array[i]=rand() % 301 + (-150);// creates random numbers from -150     to 150
  }
  for (i=0; i<N; ++i) {
    printf(" %d\n", array[i]);
  }

  pthread_t Th;
  pthread_create(&Th, NULL,Sum, (void*)N); //creates thread

  printf("%d\n",T1);
  return (0);
 }`    

I tried changing pthread_exit(NULL); to return(0) or return(T1) but it didn't work. I changed the Sum function to:

    void *Sum(void *N){ //function used by thread to calculate sum
      printf("I am the 1st thread i ll calculate the sum for you");
      pthread_exit(NULL);
   }

It didn't work either.the output I get anyway is :

0
give the size of the array please
2
 117
 113
0

Note that I get no compile errors or warnings.

P.P
  • 117,907
  • 20
  • 175
  • 238
John Vn
  • 81
  • 2
  • 10
  • 3
    You forgot to join your thread. – Kerrek SB Dec 17 '15 at 20:29
  • 1
    From `man pthread_join`: `pthread_join -- wait for thread termination` – Fiddling Bits Dec 17 '15 at 20:33
  • the posted code has a few problems. When compiling, always enable all the warnings (for gcc, at a minimum use: `-Wall -Wextra -pedantic` ) then fix those problems. 1) there is a 'stray' ' after the closing brace of the function `main()`. 2) the parameters for `main()` are not used, suggest `int main( void )` – user3629249 Dec 18 '15 at 15:59
  • In C, when calling `malloc()`, do not cast the returned value as that value type is already `void*` so can be assigned to any other pointer. Casting the returned value just clutters the code and makes debugging and/or maintaining the code that much harder. Always check (!=NULL) the returned value to assure the operation was successful – user3629249 Dec 18 '15 at 16:01
  • when calling `scanf()` (and family of functions) always check the returned value (not the parameter value) to assure the operation was successful. For this line: `scanf("%ld", &N);` any returned value but 1 means the operation failed. – user3629249 Dec 18 '15 at 16:04
  • before calling `rand()`, always call `srand(seed)` to create a random sequence. Suggest: `#include ` and `srand( time(NULL) );` Note: `srand()` should only be called once, so place that call before the loop – user3629249 Dec 18 '15 at 16:06
  • the `_` operator has a higher precedence than the `%` operator, so this line: `array[i]=rand() % 301 + (-150);` should be similar to: `array[i]= -150 + (rand() % 301);` I.E. use parens to get the desired sequence of operations – user3629249 Dec 18 '15 at 16:11
  • this line: `long S=(long) N;` has the problem that a void pointer should not be cast to a long int. Suggest correcting this line:`pthread_create(&Th, NULL,Sum, (void*)N);` to: `pthread_create(&Th, NULL,Sum, (void*)&N);` then correcting this line: `long S=(long) N;` to: `long S=(long) *N;` – user3629249 Dec 18 '15 at 16:19

2 Answers2

4

1) Your main() thread is not waiting for the thread to complete. So your thread Sum may not get executed at all. Call pthread_join():

pthread_create(&Th, NULL,Sum, &N); 
pthread_join(Th, 0); // waits for the thread "Sum"

2) You are declaring and assigning array again in main(). So the allocation is only for the array in main() since it shadows the global variable. This leads to undefined behaviour as the array you write into in Sum thread wasn't allocated any memory. So

  int *array= (int*) malloc((N)*sizeof(int)); // dynamic array

should be

  array= malloc((N)*sizeof(int)); 

A void* can be converted to any other object pointer automatically. So the cast is unnecessary and potentially dangerous.

3) Integer to pointer conversion has implementation defined behaviour. So I would avoid it. Since the thread only reads N, you can pass the address of it:

pthread_create(&Th, NULL,Sum, &N); //creates thread

and in the thread function do:

  long S=*((long*) N);
P.P
  • 117,907
  • 20
  • 175
  • 238
2
pthread_create(&Th, NULL,Sum, (void*)N); //creates thread

After this line you need to to either join or detach the thread. In this case you'll want to join the thread or your program will end right away.

pthread_join(Th, NULL);
FrozenHawk
  • 150
  • 2
  • 8
  • Thank you for the answer.when i use `pthread_join(Th, NULL); `i get a Segmentation fault.Any suggestions why? – John Vn Dec 17 '15 at 20:41