Search code examples
cmultithreadingpthreadssemaphorebarrier

Find max in array using threads?


How would you do this in c with a binary reduction and a barrier implemented using binary semaphores? This is the code I have so far. It doesnt have a barrier, and I'm confused on how to make one. Would I need mutex locks for this?

# include <stdio.h>
# include <pthread.h>
# define arrSize 10

struct StructMax
{
    int iMax;
};

int arr[arrSize];

void *thread_search_max(void *);

int main()
{
    pthread_t tid;
    struct StructMax *st_main,*st_th;
    int FinalMax;

    st_main=(struct StructMax*)malloc(sizeof(struct StructMax));

    int iCount;
    for(iCount=0;iCount<arrSize;iCount++)
    {
        printf("Enter Value of arr[%d] :",iCount);
        scanf("%d",&arr[iCount]);
    }        
    pthread_create(&tid,NULL,thread_search_max,NULL);

    st_main->iMax=arr[0];

    for(iCount=1;iCount<arrSize/2;iCount++)
    {
        if(arr[iCount] > st_main->iMax)
        {
            st_main->iMax=arr[iCount];
        }
    }    

    pthread_join(tid,(void**)&st_th);    

    if(st_main->iMax >= st_th->iMax)
    {
        FinalMax=st_main->iMax;
    }    
    else
    {
        FinalMax=st_th->iMax;
    }


    printf("Final Max : %d \n",FinalMax);
    return 0;
}


void *thread_search_max(void *para)
{
    struct StructMax *st;
    st=(struct StructMax*)malloc(sizeof(struct StructMax));

    int iCount;
    st->iMax=arr[arrSize/2];


    for(iCount=arrSize/2 + 1;iCount<arrSize;iCount++)
    {
        if(arr[iCount] > st->iMax)
        {
            st->iMax=arr[iCount];
        }
    }    

    pthread_exit((void*)st);        
}

Solution

  • You didn't include stdlib.h: which is the main problem, but you should also consider some other minor fixes that would make your code robust.

    The problem with not includeing stdlib.h is that the compiler assumes that malloc() returns an int, so you can see that this will cause problems.

    If you enable compiler warnings, you can prevent this kind of things, I sometimes forget some headers, but I don't get too far because the compiler reminds me.

    Assuming that you work with gcc then

    gcc -Wall -Werror -o output $sourceFiles -pthread
    

    will prevent compilation in this case.

    This is an improved version of your program, with the stdlib.h header included

    #include <stdio.h>
    #include <stdlib.h>
    #include <pthread.h>
    
    #define arrSize 10
    
    struct StructMax
    {
        int iMax;
    };
    
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    
    void *thread_search_max(void *);
    
    int main()
    {
        pthread_t         tid;
        struct StructMax *st_main;
        struct StructMax *st_th;
        int               FinalMax;
        int               arr[arrSize];
    
        st_main = malloc(sizeof(struct StructMax));
        if (st_main == NULL)
            return -1;
        int iCount;
        for (iCount = 0 ; iCount < arrSize ; iCount++)
        {
            printf("Enter Value of arr[%d] :",iCount);
            scanf("%d",&arr[iCount]);
        }
        pthread_create(&tid, NULL, thread_search_max, arr);
    
        /* lock the mutex, in this secction we access 'arr' */
        pthread_mutex_lock(&mutex);
        st_main->iMax = arr[0];
        pthread_mutex_unlock(&mutex);
    
        for (iCount = 1 ; iCount < arrSize / 2 ; iCount++)
        {
            /* lock the mutex, in this secction we access 'arr' */
            pthread_mutex_lock(&mutex);
            if (arr[iCount] > st_main->iMax)
            {
                st_main->iMax = arr[iCount];
            }
            pthread_mutex_unlock(&mutex);
        }
        pthread_join(tid, (void **)&st_th);
    
        if (st_main->iMax >= st_th->iMax)
        {
            FinalMax = st_main->iMax;
        }
        else
        {
            FinalMax = st_th->iMax;
        }
        printf("Final Max : %d \n", FinalMax);
        free(st_th);
        free(st_main);
        return 0;
    }
    
    void *thread_search_max(void *para)
    {
        struct StructMax *st;
        int               iCount;
        int              *arr;
    
        arr = para;
        if (arr == NULL)
            return NULL;
        st = malloc(sizeof(struct StructMax));
        if (st == NULL)
            return NULL;
        /* lock the mutex, in this secction we access 'arr' */
        pthread_mutex_lock(&mutex);
        st->iMax = arr[arrSize/2];
        pthread_mutex_unlock(&mutex);
        for (iCount = arrSize /  2 + 1 ; iCount < arrSize ; iCount++)
        {
            /* lock the mutex, in this secction we access 'arr' */
            pthread_mutex_lock(&mutex);
            if (arr[iCount] > st->iMax)
            {
                st->iMax = arr[iCount];
            }
            pthread_mutex_unlock(&mutex);
        }
        pthread_exit((void *)st);
    }
    

    see the usage of the mutex, it prevents the two threads from accessing the value simultaneously. And how global variables are not needed, besides they are a really bad idea when multithreading.