Segmentation Fault at pthread_join

angyxpoo picture angyxpoo · Nov 25, 2013 · Viewed 20.4k times · Source

So when I run my code, I'm getting a segmentation fault right at the pthread_join. There is a print statement after my pthread_join that doesn't run. Does anyone have any idea why? Could you give me some hints or ideas as to how to figure this out??

the output prints out all of row numbers for my matrix until the end, then it leaves matrixCalc function and prints "after threads are created". This happens when I put in an argument for 1 thread.

I've included a small section of my code here:

int main(int argc, char*argv[]) 
{
  //takes in number of threads as 1st arg
  pthread_attr_init(&attr);
  //initialize matrix here

  //passes num of threads through matrixcalc
  for(i = 0; i < numberOfThreads; i++)
    {
      threadCount++;
      pthread_create(&tid, &attr, matrixCalc(threadCount), NULL);  
    }
  printf("after threads are created\n");
  pthread_join(tid, NULL);  
  printf("after join\n");
  exit(0);
  return 0;
}

Here is matrix calc function:

    void *matrixCalc(threadCount) 
{
  int i, j, sum, tempNum, currentRow;
  currentRow = threadCount;
  sum=0;

  while(currentRow < 1200)
    {
      //cycles through the column j for matrix B
      for(j=0; j<500; j++)
        {
          //cycles through the diff i values for the set row in matrix A and column in matrix B
          for(i=0; i<1000; i++)
            {
              //Matrix A set i value is at threadcount-1
              //Matrix B i value = j
              //Matrix B j value = i
              //Multiply together and add to sum
              tempNum = (matrixA[currentRow-1][i])*(matrixB[i][j]);
              sum = sum+tempNum;
            }
          //Set Matrix C at i value = currentRow and jvalue = i to sum
          matrixC[currentRow-1][j] = sum;
          //printf("%d\n", matrixC[currentRow-1][i]);
        }
        //increase threadcount by number of threads 
        //until you hit max/past max val
        currentRow = currentRow + nThreads;
        //printf("%d\n", currentRow);
    }
    return NULL;

}

Answer

alk picture alk · Nov 25, 2013

When calling pthread_create() you need to pass the address of a function of type void *(*)(void *). What the code does is calling a function there so its result is getting passed to pthread_create().

Change this line

pthread_create(&tid, &attr, matrixCalc(threadCount), NULL);  

to become

pthread_create(&tid, &attr, matrixCalc, NULL);  

or

pthread_create(&tid, &attr, &matrixCalc, NULL);  

which in fact is the same.


As already mentioned above the thread function needs to be declared as void *(*)(void *).

So change this

 void *matrixCalc(threadCount) 

will will become this

 void * matrixCalc(void *) 

As the code seems to try to spawn off multiple threads and all should be joined perpare room to store the several pthread-ids.

This could for example be done using an array like this:

pthread_t tid[numberOfThreads] = {0};

Then create the thread like this:

pthread_create(&tid[i], &attr, matrixCalc, NULL);

To passed the thread number (counter i) down to the thread also give it room by defining

int thread_counts[numberOfThreads] = {0};

assign it and pass it as 4th parameter on the thread's creation:

 thread_counts[i] = i;
 pthread_create(&tid[i], &attr, matrixCalc, &thread_Counts[i]);

Down in the thread function then get it by modifying

void *matrixCalc(threadCount) 
{
  int i, j, sum, tempNum, currentRow;
  currentRow = threadCount;
  ...

like this:

void * matrixCalc(void * pv) 
{
  int i, j, sum, tempNum, currentRow;
  currentRow = *((int*) pv);
  ...

Finally to join all thread replace the single call to pthread_join() by a loop:

for (i = 0; i < numberOfThreads; ++i)
{
  pthread_join(tid[i], NULL);  
}