Segmentation Fault at pthread_join - c

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

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

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void * (*start_routine) (void *), void *arg);
The third parameter is a start function taking a void ptr and returning a void ptr.
The fourth parameter takes a void ptr pointing to the data you want to pass, in this case threadcnt.

Related

pthread_join hangs accordingly to random global variable value

I have built this code utilizing pthreads. The goal is to build an array X[N][D] and assign random values to it. You could read the elements of this array as the coefficients of some points.
On the next step I am trying to calculate an array distances[N]which holds all the distances between the last element (Nth) and each other element. The distances calculation is executed using pthreads.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
#define N 10
#define D 2 //works for any d
#define NUM_THREADS 8
//double *distances;
//int global_index = 0;
pthread_mutex_t lock;
double *X;
typedef struct
{
//int thread_id;
double *distances;
int *global_index ;
pthread_mutex_t lock;
double *X;
}parms;
void *threadDistance(void *arg)
{
parms *data = (parms *) arg;
double *distances = data->distances;
double *X = data->X;
int *global_idx = data -> global_index;
int idx,j;
//long id = (long)arg;
pthread_mutex_lock(&lock);
while(*global_idx<N)
{
//printf("Thread #%ld , is calculating\n", id);
idx = *(global_idx);
(*global_idx)++;
pthread_mutex_unlock(&lock);
for(j=0 ; j<D; j++)
{
distances[idx] = pow(X[(j+1)*N-1]-X[j*N+idx], 2);
//printf("dis[%d]= ", dis);
//printf("%f\n",distances[idx]);
}
//printf("global : %d\n", *global_idx);
}
pthread_exit(NULL);
}
void calcDistance(double * X, int n, int d)
{
int i;
int temp=0;
pthread_t threads[NUM_THREADS];
double *distances = malloc(n * sizeof(double));
parms arg;
arg.X = X;
arg.distances = distances;
arg.global_index = &temp;
for (i=0 ; i<NUM_THREADS ; i++)
{
pthread_create(&threads[i], NULL, threadDistance, (void *) &arg);
}
for(i = 0 ; i<NUM_THREADS; i++)
{
pthread_join(threads[i], NULL);
}
/*----print dstances[] array-------*/
printf("--------\n");
for(int i = 0; i<N; i++)
{
printf("%f\n", distances[i]);
}
/*------------*/
free(distances);
}
int main()
{
srand(time(NULL));
//allocate the proper space for X
X = malloc(D*N*(sizeof(double)));
//fill X with numbers in space (0,1)
for(int i = 0 ; i<N ; i++)
{
for(int j=0; j<D; j++)
{
X[i+j*N] = (double) (rand() / (RAND_MAX + 2.0));
}
}
calcDistance(X, N, D);
return 0;
}
The problem is that the code executes completely only when N=100000. If N!=100000 the code just hangs and I have found that the source of the problem is the pthread_join() function. First of all I cannot understand why the hang depends on the value of N.
Secondly, I have tried printf()ing the value of global_index (as you can see it is commented out in this particular sample of code). As soon as I uncomment the printf("global : %d\n", *global_idx); command the program stops hanging, regardless of the value of N.
It seems crazy to me as the differences between hanging and not hanging are so irrelevant.
regarding:
pthread_mutex_lock(&lock);
while(*global_idx<N)
{
// ...
pthread_mutex_unlock(&lock);
The result is that after the first iteration of the loop, the mutex is always unlocked. Suggest moving the call to pthread_mutex_lock() to inside the top of the loop.
after making the above corrections, I then set N to 10000. Then re-compiled, etc. The result was a seg fault event, so the mis-handling of the mutex is not the only problem.
regarding:
* First of all I cannot understand why the hang depends on the value of N.*
it seems the program is actually crashing with a seg fault event, not hanging

Passing array pointer into function in C

I'm working in C, and I'm trying to pass in a pointer to an array that will hold my thread ids, but I cannot seem to get my types to match. What am I not understanding about passing pointers in C?
This is my function:
int createThreads(int numThreads, pthread_t **tidarray) {
pthread_t *tids = *tidarray;
int i;
for (i = 0; i < numThreads; i++) {
pthread_create(tids + i, NULL, someFunction, NULL);
}
return 0;
}
And this is my call:
pthread_t tids[numThreads];
createThreads(5, &tids);
When I compile this, I get a warning:
Passing argument 2 of 'createThreads' from incompatible pointer type, and
Note: expected 'pthread_t **' but argument is of type 'pthread_t (*) [(long unsigned int)(numThreads)]'
#include <stdio.h>
#include <pthread.h>
// dummy function for threads , it just print its argument
void * someFunction(void *data){
printf("Thread %d\n",(int)data);
}
int createThreads(int numThreads, pthread_t *tidarray) {
int i;
for (i = 0; i < numThreads; i++) {
//pass the pointer of the first element + the offset i
pthread_create(tidarray+i, NULL, someFunction, (void*)i);
}
return 0;
}
int main(){
pthread_t tids[5]={0};// initialize all to zero
createThreads(5, tids);
getchar();// give time to threads to do their job
// proof-of-concept, the array has been filled by threads ID
for(int i=0;i<5;i++)
printf("Thread (%d) ID = %u\n",i,tids[i]);
return 0;
}
You don't need the & address of operator, just pass it as it is because it's converted to a pointer automatically, so
createThreads(5, tids);
is what you need, and then your createThreads() function
int createThreads(int numThreads, pthread_t *tids)
{
int i;
for (i = 0; i < numThreads; i++)
{
pthread_create(tids + i, NULL, someFunction, NULL);
}
return 0;
}

pthread same ID and output self_t

i hope i will put my question very clear, i am programming pthread,Briefly i calculate the number of threads needed, and pass created threads to a function and back, the function does transpose on different blocks; so each thread has its own block.
To check that im sending different threads, i run pthread_t self_t, but face two problems:
that seems only one same thread is used, and that i always have warning message about the type output of selt_t, below code simplified showing main pints.
any ideas where i went wrong ?
First here struct and main:
pthread_mutex_t mutexZ; // Mutex initialize
int array[nn][nn];
struct v
{
int i, j; // threaded Row,Col
int n, y; //
int iMAX; //
};
void *transposeM(void *arg);
int main(int argc, char *argv[])
{
int Thread_Num = 10;
pthread_t t_ID[Thread_Num]; // the number of threads depending on # blocks
printf("Thread_Num %d\n", Thread_Num);
struct v *data = (struct v *) malloc(sizeof(struct v));
int i, j; //loop varables
//#############################################################
printf("Matrix Initial before Transpose Done\n");
// printing the Matrix Before any transpose if needed testing
for (i = 0; i < nn; i++){
for(j = 0; j< nn; j++){
array[i][j] = i*nn + j;
printf("%d ", array[i][j]);
}
printf("\n");}
//************************************************************/
// Initialize the mutex
pthread_mutex_init(&mutexZ, NULL);
pthread_attr_t attr; //Set of thread attributes
pthread_attr_init(&attr);
int n, y; // Loop Variables for tiling
//************************************************************/
//Start of loop transpose:
int start = 0;
for (n = 0; n < nn; n += TILE)
{
data->n = n; // row
for (y = 0; y <= n; y += TILE) {
data->y = y; // column
printf("y Tile:%d \n", y);
printf("Start before:%d \n", start);
//Transpose the other blocks, thread created for each Block transposed
pthread_create(&(t_ID[start]), NULL, transposeM, (void*) data); // Send the thread to the function
pthread_join(t_ID[start], NULL);
if (start < Thread_Num)
{
start = start + 1;
}
printf("Start after:%d \n", start);
} // End the Y column TileJump loop
} // End of n Row TileJump loop
}
Modified according to the notes,
void *transposeM(void *arg)
{
// Transposing the tiles
struct v *data = arg;
int i, j; //loop row and column
int temp = 0;
pthread_mutex_lock(&mutexZ); //lock the running thread here,so keeps block until thread that holds mutex releases it
pthread_t self_t; // To check the thread id - my check not Mandetory to use
self_t = pthread_self();
printf("Thread number Main = %u \n ", self_t); //here we used u% coz seems the pthread_t is unsigned long data type
//*******************************************************
//here some function to work
//########################################################
pthread_mutex_unlock(&mutexZ);
pthread_exit(NULL);
return (NULL);
} // End
There are two conceptual issues with your code:
You pass the same reference/addrerss to each thread, making each thread work on the same data.
You join the thread immediately after having created it. As joining block until the thread to be joined ended, this sequentialises the running of all threads.
To get around 1. created a unique instance of what data points to for each thread.
To fix 2. move the call to pthread_join() out of the loop creating the threads and put it in a 2nd loop run after creation-loop.
...
printf("Thread_Num %d\n", Thread_Num);
pthread_t t_ID[Thread_Num]; // the number of threads depending on # blocks
struct v data_ID[Thread_Num] = {0}; // define an instance of data for ech thread
...
for (n = 0; n < nn; n += TILE) //limit of row
{
struct v * data = data_ID + start; // assign thread specific instance
data->n = n; // row
for (y = 0; y <= n; y += TILE) // limit of column -here removd the =n, then diagonal tile is not transposed
{
...
pthread_create(&(t_ID[start]), NULL, transposeM, (void*) data); // Send the thread to the function
...
}
} // End the Y column TileJump loop
for (;start >= 0; --start)
{
pthread_join(t_ID[start], NULL);
}
...
Modifications to the thread function:
void *transposeM(void *arg)
{
struct v *data = arg;
...
pthread_t self = pthread_self(); // better naming
...
pthread_exit(NULL); // the thread functions exits here.
return NULL; // this is never reached, but is necessary to calm down thr compiler.
} // End

pthread Return Values to an Array

I am currently working on a project that uses pthreads. The project so far starts a user specified number of threads and does some work on each thread then closes. Each thread is stored in a dynamically allocated array of memory. I do this using:
threads = malloc(number_of_threads * sizeof(pthread_t));
Then I create each thread in a for-loop:
pthread_create(&(threads[i]), NULL, client_pipe_run, (void *) &param[i]);
What I need to do next is store the return values of these threads. My understanding is that I need to pass pthread_join the address of a pointer I want to have the return value stored in. This is where I get a little confused. I'm fine with pointers up to this point then my brain kind of has a melt down haha. This is my idea on how to acheive this but I'm not confident that this is correct:
int *return_vals = malloc(sizeof(int) * number_of_threads);
for(i = 0; i< number_of_threads; i++)
{
pthread_join(&(threads[i]),(void *) &(return_vals[i]));
}
Then to get the return value I would do something similar to:
int val = *(return_val[0]);
Any help on the this would be greatly appreciated!
Note that you are allocating memory for your threads like this:
threads = malloc(number_of_thread * sizeof(pthread_t));
but for return values you do:
int *return_vals = malloc(sizeof(int *));
i.e. number of threads should be taken in count here too:
int *return_vals = malloc(number_of_thread * sizeof(int));
Then you can either cast the return value to void*:
void *foo(void *arg) {
int i = 7;
return (void*)i;
}
int main(void) {
int i = 0;
int thread_count = 3;
pthread_t* threads = malloc(thread_count * sizeof(pthread_t));
int *return_vals = malloc(thread_count * sizeof(int));
// create threads:
for(i = 0; i < thread_count; ++i)
pthread_create(&threads[i], NULL, &foo, NULL);
// wait untill they finish their work:
for(i = 0; i < thread_count; ++i)
pthread_join(threads[i], (void**) &return_vals[i]);
// print results:
for(i = 0; i < thread_count; ++i)
printf("Thread %d returned: %d\n", i, return_vals[i]);
// clean up:
free(return_vals);
free(threads);
return 0;
}
or you can make sure that your code doesn't make any presumptions about size of the type you're returning being less or equal to sizeof(void*) and allocate the memory for the return value dynamically within the thread:
void *foo(void *arg) {
int* ret = malloc(sizeof(int));
*ret = 7;
return ret;
}
int main(void) {
int i = 0;
int thread_count = 3;
pthread_t* threads = malloc(thread_count * sizeof(pthread_t));
// array of pointers to return values of type int:
int **return_vals = calloc(thread_count, sizeof(int*));
// create threads:
for(i = 0; i < thread_count; ++i)
pthread_create(&threads[i], NULL, &foo, NULL);
// wait untill they finish their work:
for(i = 0; i < thread_count; ++i)
pthread_join(threads[i], (void**) &return_vals[i]);
// print results:
for(i = 0; i < thread_count; ++i)
printf("Thread %d returned: %d\n", i, *return_vals[i]);
// clean up:
for(i = 0; i < thread_count; ++i)
free(return_vals[i]);
free(return_vals);
free(threads);
return 0;
}
But in case you chose the latter one, be careful about possible memory leaks you might end up with.

Matrix multiplication using pthreads

I am trying to do matrix multiplication using pthreads and creating one thread for each computation of each row instead of each element. Suppose there are two matrices
A[M][K],B[K][N] . Where am I going wrong ?
int A[M][K];
int B[K][N];
int C[][];
void *runner (void *param);
struct v
{
int i;
int j;
};
pthread_t tid[M];
for (i = 0; i < M; i++) // It should create M threads
{
struct v *data = (struct v *) malloc (sizeof (struct v));
data->i = i;
data->j = j;
pthread_create (&tid[count], &attr, runner, data);
pthread_join (tid[count], NULL);
count++;
}
runner (void *param) //
{
struct v *test;
int t = 0;
test = (struct v *) param;
for (t = 0; t < K; t++) // I want to compute it for a row instead of an element
{
C[test->i][test->j] = C[test->i][test->j] + A[test->i][t] * B[t][test->j];
}
pthread_exit (0);
}
First, get rid of data->j. If you are computing entire rows the row index is the only thing your thread needs. Right now your runner(..) computes a single element. You have to iterate over all row elements computing them one by one.
Second, do not join a thread right after it is created. This way you have only one thread running at a time. Start joining threads when all threads have been created.

Resources