0

I have got troubles with my code. The following code starts n threads that compete to find the max value of each diagonal of n different matrices.

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <time.h>
#include <semaphore.h>

void crea_matrix(int **);
void trova_max(void *);

struct bin_sem
{
    pthread_mutex_t mutex;
    pthread_cond_t  cond;
    int cnt;
}    shared= {PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER };

int n,**matrix,max;

int main ()
{   

    int i;
    srand(time(NULL));
    printf("N of matrices: \n");
    scanf("%d", &n);
    int **matrix = (int **)malloc(3 * sizeof(int *));
     for (i=0; i<3; i++)
         matrix[i] = (int *)malloc(3 * sizeof(int));

    pthread_t *tids;
    tids=malloc(n*sizeof(pthread_t));
    for(i=0;i<n;i++)
        pthread_create(tids+i,NULL,trova_max,matrix);
    for(i=0;i<n;i++)
    {
        pthread_mutex_lock(&shared.mutex);
        max=0;
        crea_matrix(matrix);
        shared.cnt=i;
        pthread_cond_signal(&shared.cond);
        pthread_mutex_unlock(&shared.mutex);
        sleep(1);
    }
    for(i=0;i<n;i++)
        pthread_join(tids[i],NULL);
}

void crea_matrix(int **matrix)
    {
    int i,j;
    for(i=0;i<3;i++)
        for(j=0;j<3;j++)
    matrix[i][j]=rand()%101;
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
            printf("%d ",matrix[i][j]);
        printf("\n");
    }


}


void trova_max(void* arg)
{
    int i=0, j=0;
    int **arr2d;
    arr2d=(int**)arg;
    do
    {
        pthread_mutex_lock(&shared.mutex);
        pthread_cond_wait(&shared.cond,&shared.mutex);
        printf("\nThread: %ld took control of the mutex...\n",(long int)     pthread_self());
        for(i=0;i<3;i++)
        {

            if(arr2d[i][i]>max)
                max=arr2d[i][i];
                printf("\nFirst diag max: %d\n",max);
        }
    i=0;

        for (j=2;j>=0;j--)
        {
            printf("\nSecond diag max:  %d\n",max);
                if (arr2d[i][j]>max)
                    max=arr2d[i][j];
        i++;
        }
    printf("Max found: %d,matrix n° %d", max,shared.cnt);
    pthread_mutex_unlock(&shared.mutex);
    } while(shared.cnt !=n-1);


    pthread_exit(NULL);

}

The thing is, most of my code works, but when the max evaluations are done, only 1 thread gets access to the pthread_exit(NULL); line. I am struggling to find a solution, Hope you can help me. Thanks.

Giulio Paoli
  • 85
  • 11
  • 1
    Concurrent access to `shared.cnt` is not protected. This is not good. – alk Jun 25 '16 at 11:05
  • And please properly indent your code, as this not just ugly, but also very difficult to read. – alk Jun 25 '16 at 11:06
  • Also just remove all those useless casts. In C there is no need to cast from/to `void`-pointers, not is it recommended in any way. – alk Jun 25 '16 at 11:09
  • I'm sorry, I'm actually new to SO and i'm having a hard time indenting. – Giulio Paoli Jun 25 '16 at 11:09
  • In Eclipse (assuming TABs are off and TAB replacement is set to 2) for example just do: Ctrl-Shift-F Alt-A Tab Tab Ctrl-C come here and do Ctrl-V :-) – alk Jun 25 '16 at 11:12

1 Answers1

1

Referring to this question: Is it guaranteed that pthread_cond_signal will wake up a waiting thread?

It is possible that the remaining threads are still blocked on pthread_cond_wait. Doing a final pthread_cond_broadcast before the join will release all the blocked threads.

However, this solution will bring its own set of problems as all the threads will eventually execute the body of the loop. You may have to add an extra check for shared.cnt != n-1. That has to be done atomically though as noticed in one of the comments.

Community
  • 1
  • 1
Tarik
  • 10,810
  • 2
  • 26
  • 40